Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialCreateMassMessageList
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 10
600
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
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getFormFields
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onSubmit
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
132
 onSuccess
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getContentOptions
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 getTargets
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 getDisplayFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\MassMessage\Specials;
4
5use MediaWiki\HTMLForm\HTMLForm;
6use MediaWiki\MassMessage\Content\MassMessageListContentHandler;
7use MediaWiki\MassMessage\Lookup\SpamlistLookup;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\SpecialPage\FormSpecialPage;
10use MediaWiki\Status\Status;
11use MediaWiki\Title\Title;
12use MediaWiki\WikiMap\WikiMap;
13
14class SpecialCreateMassMessageList extends FormSpecialPage {
15
16    public function __construct() {
17        parent::__construct( 'CreateMassMessageList', 'editcontentmodel' );
18    }
19
20    public function doesWrites() {
21        return true;
22    }
23
24    /**
25     * Add ResourceLoader module and call parent implementation.
26     *
27     * @param string|null $par
28     */
29    public function execute( $par ) {
30        $this->addHelpLink( 'Help:Extension:MassMessage' );
31        parent::execute( $par );
32    }
33
34    /**
35     * @return array
36     */
37    protected function getFormFields() {
38        $this->getOutput()->addModules( 'ext.MassMessage.create' );
39        return [
40            'title' => [
41                'type' => 'text',
42                'label-message' => 'massmessage-create-title',
43            ],
44            'description' => [
45                'type' => 'textarea',
46                'rows' => 5,
47                'useeditfont' => true,
48                'label-message' => 'massmessage-create-description',
49            ],
50            'content' => [
51                'type' => 'radio',
52                'options' => $this->getContentOptions(),
53                'default' => 'new',
54                'label-message' => 'massmessage-create-content',
55            ],
56            'source' => [
57                'type' => 'title',
58                'creatable' => true,
59                'label-message' => 'massmessage-create-source',
60                'hide-if' => [ '!==', 'content', 'import' ],
61            ],
62        ];
63    }
64
65    /**
66     * Add an ID to the form for targeting with JS code.
67     *
68     * @param HTMLForm $form
69     */
70    protected function alterForm( HTMLForm $form ) {
71        $form->setId( 'mw-massmessage-create-form' );
72    }
73
74    /**
75     * @param array $data
76     * @return Status
77     */
78    public function onSubmit( array $data ) {
79        $title = Title::newFromText( $data['title'] );
80        $pm = MediaWikiServices::getInstance()->getPermissionManager();
81        if ( !$title ) {
82            return Status::newFatal( 'massmessage-create-invalidtitle' );
83        } elseif ( $title->exists() ) {
84            return Status::newFatal( 'massmessage-create-exists' );
85        } elseif ( !$pm->userCan( 'edit', $this->getUser(), $title ) ||
86            !$pm->userCan( 'editcontentmodel', $this->getUser(), $title )
87        ) {
88            return Status::newFatal( 'massmessage-create-nopermission' );
89        }
90
91        if ( $data['content'] === 'import' ) {
92            // We're importing from an existing list
93            $source = Title::newFromText( $data['source'] );
94            if ( !$source ) {
95                return Status::newFatal( 'massmessage-create-invalidsource' );
96            }
97
98            $targets = $this->getTargets( $source );
99            if ( $targets === null || count( $targets ) === 0 ) {
100                return Status::newFatal( 'massmessage-create-invalidsource' );
101            }
102            if ( $source->inNamespace( NS_CATEGORY ) ) {
103                $editSummaryMsg = $this->msg(
104                    'massmessage-create-editsummary-catimport',
105                    $source->getPrefixedText()
106                );
107            } else {
108                $editSummaryMsg = $this->msg(
109                    'massmessage-create-editsummary-import',
110                    $source->getPrefixedText(),
111                    $source->getLatestRevID()
112                );
113            }
114        } else {
115            $targets = [];
116            $editSummaryMsg = $this->msg( 'massmessage-create-editsummary' );
117        }
118
119        $result = MassMessageListContentHandler::edit(
120            $title,
121            $data['description'],
122            $targets,
123            $editSummaryMsg->inContentLanguage()->plain(),
124            false,
125            'preferences',
126            $this->getContext()
127        );
128
129        if ( !$result->isGood() ) {
130            return $result;
131        }
132
133        $this->getOutput()->redirect( $title->getFullUrl() );
134        return Status::newGood();
135    }
136
137    public function onSuccess() {
138        // No-op: We have already redirected.
139    }
140
141    /**
142     * Build and return the associative array for the content radio button field.
143     *
144     * @return array
145     */
146    protected function getContentOptions() {
147        $mapping = [
148            'massmessage-create-new' => 'new',
149            'massmessage-create-import' => 'import',
150        ];
151
152        $options = [];
153        foreach ( $mapping as $msgKey => $option ) {
154            $options[$this->msg( $msgKey )->escaped()] = $option;
155        }
156        return $options;
157    }
158
159    /**
160     * Get targets from an existing delivery list or category;
161     * returns null on failure.
162     *
163     * @param Title $source
164     * @return array|null
165     */
166    protected function getTargets( Title $source ) {
167        $pages = SpamlistLookup::getTargets(
168            $source,
169            /* $normalize = */ false
170        );
171        if ( $pages === null ) {
172            return null;
173        }
174
175        $currentWikiId = WikiMap::getCurrentWikiId();
176        $targets = [];
177        foreach ( $pages as $page ) {
178            $target = [ 'title' => $page['title'] ];
179            if ( $page['wiki'] !== $currentWikiId ) {
180                $target['site'] = $page['site'];
181            }
182            $targets[] = $target;
183        }
184        return MassMessageListContentHandler::normalizeTargetArray( $targets );
185    }
186
187    /**
188     * @return string
189     */
190    protected function getDisplayFormat() {
191        return 'ooui';
192    }
193}