Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 179
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialCentralNoticeLogs
0.00% covered (danger)
0.00%
0 / 179
0.00% covered (danger)
0.00%
0 / 6
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
 execute
0.00% covered (danger)
0.00%
0 / 128
0.00% covered (danger)
0.00%
0 / 1
210
 dateSelector
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 showLog
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 getDateValue
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getLogSwitcher
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3use MediaWiki\Html\Html;
4
5class SpecialCentralNoticeLogs extends CentralNotice {
6    /** @var string */
7    public $logType = 'campaignsettings';
8
9    public function __construct() {
10        // Register special page
11        SpecialPage::__construct( "CentralNoticeLogs" );
12    }
13
14    /**
15     * Handle different types of page requests
16     * @param string|null $sub
17     */
18    public function execute( $sub ) {
19        global $wgExtensionAssetsPath;
20
21        $out = $this->getOutput();
22        $request = $this->getRequest();
23
24        $this->logType = $request->getText( 'log', 'campaignsettings' );
25
26        // Begin output
27        $this->setHeaders();
28
29        // Output ResourceLoader module for styling and javascript functions
30        $out->addModules( 'ext.centralNotice.adminUi' );
31
32        // Initialize error variable
33        $this->centralNoticeError = false;
34
35        // Allow users to add a custom nav bar (T138284)
36        $navBar = $this->msg( 'centralnotice-navbar' )->inContentLanguage();
37        if ( !$navBar->isDisabled() ) {
38            $out->addHTML( $navBar->parseAsBlock() );
39        }
40        // Show summary
41        $out->addWikiMsg( 'centralnotice-summary' );
42
43        // Begin Banners tab content
44        $out->addHTML( Html::openElement( 'div', [ 'id' => 'preferences' ] ) );
45
46        $htmlOut = '';
47
48        // Begin log selection fieldset
49        $htmlOut .= Html::openElement( 'fieldset', [ 'class' => 'prefsection' ] );
50
51        $title = SpecialPage::getTitleFor( 'CentralNoticeLogs' );
52        $actionUrl = $title->getLocalURL();
53        $htmlOut .= Html::openElement( 'form', [ 'method' => 'get', 'action' => $actionUrl ] );
54        $htmlOut .= Xml::element( 'h2', null, $this->msg( 'centralnotice-view-logs' )->text() );
55        $htmlOut .= Html::openElement( 'div', [ 'id' => 'cn-log-switcher' ] );
56        $title = SpecialPage::getTitleFor( 'CentralNoticeLogs' );
57        $fullUrl = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
58
59        // Build the radio buttons for switching the log type
60        $htmlOut .= $this->getLogSwitcher( 'campaignsettings', 'campaignSettings',
61            'centralnotice-campaign-settings', $fullUrl );
62        $htmlOut .= $this->getLogSwitcher( 'bannersettings', 'bannerSettings',
63            'centralnotice-banner-settings', $fullUrl );
64        $htmlOut .= $this->getLogSwitcher( 'bannercontent', 'bannerContent',
65            'centralnotice-banner-content', $fullUrl );
66        $htmlOut .= $this->getLogSwitcher( 'bannermessages', 'bannerMessages',
67            'centralnotice-banner-messages', $fullUrl );
68
69        $htmlOut .= Html::closeElement( 'div' );
70
71        if ( $this->logType == 'campaignsettings' ) {
72            $reset = $request->getVal( 'centralnoticelogreset' );
73            $campaign = $request->getVal( 'campaign' );
74            $user = $request->getVal( 'user' );
75            $start = $this->getDateValue( 'start' );
76            $end = $this->getDateValue( 'end' );
77
78            $htmlOut .= Html::openElement( 'div', [ 'id' => 'cn-log-filters-container' ] );
79
80            $collapsedImg = $this->getContext()->getLanguage()->isRTL() ?
81                '/CentralNotice/resources/images/collapsed-rtl.png' :
82                '/CentralNotice/resources/images/collapsed-ltr.png';
83
84            if ( $campaign || $user || $start || $end ) { // filters on
85                $htmlOut .= '<a href="javascript:toggleFilterDisplay()">' .
86                    '<img src="' . $wgExtensionAssetsPath . $collapsedImg . '" ' .
87                    'id="cn-collapsed-filter-arrow" ' .
88                    'style="display:none;position:relative;top:-2px;"/>' .
89                    '<img src="' . $wgExtensionAssetsPath . '/CentralNotice/resources/images/uncollapsed.png" ' .
90                    'id="cn-uncollapsed-filter-arrow" ' .
91                    'style="display:inline-block;position:relative;top:-2px;"/>' .
92                    '</a>';
93                $htmlOut .= Html::element( 'span', [ 'style' => 'margin-left: 0.3em;' ],
94                    $this->msg( 'centralnotice-filters' )->text() );
95                $htmlOut .= Html::openElement( 'div', [ 'id' => 'cn-log-filters' ] );
96            } else { // filters off
97                $htmlOut .= '<a href="javascript:toggleFilterDisplay()">' .
98                    '<img src="' . $wgExtensionAssetsPath . $collapsedImg . '" ' .
99                    'id="cn-collapsed-filter-arrow" ' .
100                    'style="display:inline-block;position:relative;top:-2px;"/>' .
101                    '<img src="' . $wgExtensionAssetsPath . '/CentralNotice/resources/images/uncollapsed.png" ' .
102                    'id="cn-uncollapsed-filter-arrow" ' .
103                    'style="display:none;position:relative;top:-2px;"/>' .
104                    '</a>';
105                $htmlOut .= Html::element( 'span', [ 'style' => 'margin-left: 0.3em;' ],
106                    $this->msg( 'centralnotice-filters' )->text() );
107                $htmlOut .= Html::openElement( 'div',
108                    [ 'id' => 'cn-log-filters', 'style' => 'display:none;' ] );
109            }
110
111            $htmlOut .= Html::openElement( 'table' );
112
113            $htmlOut .= Html::rawElement( 'tr', [],
114                Html::rawElement( 'td', [],
115                    Xml::label( $this->msg( 'centralnotice-start-date' )->text(), 'month',
116                        [ 'class' => 'cn-log-filter-label' ] )
117                ) .
118                Html::rawElement( 'td', [],
119                    $this->dateSelector( 'start', true, $reset ? '' : $start )
120                )
121            );
122
123            $htmlOut .= Html::rawElement( 'tr', [],
124                Html::rawElement( 'td', [],
125                    Xml::label( $this->msg( 'centralnotice-end-date' )->text(), 'month',
126                        [ 'class' => 'cn-log-filter-label' ] )
127                ) .
128                Html::rawElement( 'td', [],
129                    $this->dateSelector( 'end', true, $reset ? '' : $end )
130                )
131            );
132
133            $htmlOut .= Html::rawElement( 'tr', [],
134                Html::rawElement( 'td', [],
135                    Xml::label( $this->msg( 'centralnotice-notice' )->text(), 'campaign',
136                        [ 'class' => 'cn-log-filter-label' ] )
137                ) .
138                Html::rawElement( 'td', [],
139                    Xml::input( 'campaign', 25, ( $reset || $campaign === null ? '' : $campaign ) )
140                )
141            );
142
143            $htmlOut .= Html::rawElement( 'tr', [],
144                Html::rawElement( 'td', [],
145                    Xml::label( $this->msg( 'centralnotice-user' )->text(), 'user',
146                        [ 'class' => 'cn-log-filter-label' ] )
147                ) .
148                Html::rawElement( 'td', [],
149                    Xml::input( 'user', 25, ( $reset || $user === null ? '' : $user ) )
150                )
151            );
152
153            $htmlOut .= Html::openElement( 'tr' );
154
155            $htmlOut .= Html::openElement( 'td', [ 'colspan' => 2 ] );
156            $htmlOut .= Xml::submitButton( $this->msg( 'centralnotice-apply-filters' )->text(),
157                [
158                    'id' => 'centralnoticesubmit',
159                    'name' => 'centralnoticesubmit',
160                    'class' => 'cn-filter-buttons',
161                ]
162            );
163            $link = $title->getLinkURL();
164            $htmlOut .= Xml::submitButton( $this->msg( 'centralnotice-clear-filters' )->text(),
165                [
166                    'id' => 'centralnoticelogreset',
167                    'name' => 'centralnoticelogreset',
168                    'class' => 'cn-filter-buttons',
169                    'onclick' => "location.href = " . Html::encodeJsVar( $link ) . "; return false;",
170                ]
171            );
172            $htmlOut .= Html::closeElement( 'td' );
173
174            $htmlOut .= Html::closeElement( 'tr' );
175            $htmlOut .= Html::closeElement( 'table' );
176            $htmlOut .= Html::closeElement( 'div' );
177            // @phan-suppress-next-line PhanPluginDuplicateAdjacentStatement
178            $htmlOut .= Html::closeElement( 'div' );
179        }
180
181        $htmlOut .= Html::closeElement( 'form' );
182
183        // End log selection fieldset
184        // $htmlOut .= Html::closeElement( 'fieldset' );
185
186        $out->addHTML( $htmlOut );
187
188        $this->showLog( $this->logType );
189
190        // End Banners tab content
191        $out->addHTML( Html::closeElement( 'div' ) );
192    }
193
194    /**
195     * Render a field suitable for jquery.ui datepicker
196     * @param string $prefix
197     * @param bool $editable
198     * @param string|null $date
199     * @return string HTML
200     */
201    protected function dateSelector( $prefix, $editable = true, $date = '' ) {
202        $out = Html::element( 'input',
203            [
204                'id' => "{$prefix}Date",
205                'name' => "{$prefix}Date",
206                'type' => 'text',
207                'class' => 'centralnotice-datepicker',
208            ]
209        );
210        $out .= Html::element( 'input',
211            [
212                'id' => "{$prefix}Date_timestamp",
213                'name' => "{$prefix}Date_timestamp",
214                'type' => 'hidden',
215                'value' => (string)$date,
216            ]
217        );
218        return $out;
219    }
220
221    /**
222     * Show a log of changes.
223     * @param string $logType which type of log to show
224     */
225    private function showLog( $logType ) {
226        switch ( $logType ) {
227            case 'bannersettings':
228                $pager = new CentralNoticeBannerLogPager( $this );
229                break;
230            case 'bannercontent':
231            case 'bannermessages':
232                $pager = new CentralNoticePageLogPager( $this, $logType );
233                break;
234            default:
235                $pager = new CentralNoticeCampaignLogPager( $this );
236        }
237
238        $htmlOut = '';
239
240        // Begin log fieldset
241        // $htmlOut .= Html::openElement( 'fieldset', array( 'class' => 'prefsection' ) );
242
243        // Show paginated list of log entries
244        $htmlOut .= Html::rawElement( 'div',
245            [ 'class' => 'cn-pager' ],
246            $pager->getNavigationBar() );
247        $htmlOut .= $pager->getBody();
248        $htmlOut .= Html::rawElement( 'div',
249            [ 'class' => 'cn-pager' ],
250            $pager->getNavigationBar() );
251
252        // End log fieldset
253        $htmlOut .= Html::closeElement( 'fieldset' );
254
255        $this->getOutput()->addHTML( $htmlOut );
256    }
257
258    /**
259     * Returns the jquery.ui datepicker value, or null if the field is blank.
260     * @param string $name
261     * @return null|string
262     */
263    public function getDateValue( $name ) {
264        $manual_entry = $this->getRequest()->getVal( "{$name}Date" );
265        if ( !$manual_entry ) {
266            return null;
267        }
268
269        return $this->getRequest()->getVal( "{$name}Date_timestamp" );
270    }
271
272    /**
273     * Build a radio button that switches the log type when you click it
274     * @param string $type
275     * @param string $id
276     * @param string $message
277     * @param string $fullUrl
278     * @return string HTML
279     */
280    private function getLogSwitcher( $type, $id, $message, $fullUrl ) {
281        $fullUrlEnc = Html::encodeJsVar( $fullUrl );
282        $typeEnc = Html::encodeJsVar( $type );
283        $htmlOut = '';
284        $htmlOut .= Xml::radio(
285            'log_type',
286            $id,
287            $this->logType == $type,
288            [ 'onclick' => "switchLogs( " . $fullUrlEnc . ", " . $typeEnc . " )" ]
289        );
290        $htmlOut .= Xml::label( $this->msg( $message )->text(), $id );
291        return $htmlOut;
292    }
293}