Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 99
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
CentralNoticePager
0.00% covered (danger)
0.00%
0 / 99
0.00% covered (danger)
0.00%
0 / 5
132
0.00% covered (danger)
0.00%
0 / 1
 getQueryInfo
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
20
 formatRow
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
6
 getStartBody
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
6
 getEndBody
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 bucketDropdown
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3use MediaWiki\Html\Html;
4use MediaWiki\Xml\XmlSelect;
5use Wikimedia\Rdbms\IExpression;
6use Wikimedia\Rdbms\LikeValue;
7
8class CentralNoticePager extends TemplatePager {
9
10    /**
11     * Pull banners from the database
12     * @return array[]
13     */
14    public function getQueryInfo() {
15        $dbr = CNDatabase::getReplicaDb();
16
17        // First we must construct the filter before we pull banners
18        // When the filter comes in it is space delimited, so break that...
19        $likeArray = preg_split( '/\s/', $this->filter );
20
21        // ...and then insert all the wildcards between search terms
22        if ( !$likeArray ) {
23            $likeArray = [ $dbr->anyString() ];
24        } else {
25            $anyStringToken = $dbr->anyString();
26            $tempArray = [ $anyStringToken ];
27            foreach ( $likeArray as $likePart ) {
28                $tempArray[] = $likePart;
29                $tempArray[] = $anyStringToken;
30            }
31            $likeArray = $tempArray;
32        }
33
34        // Get the current campaign and filter on that as well if required
35        $notice = $this->mRequest->getVal( 'notice' );
36        $noticeId = Campaign::getNoticeId( $notice, $dbr );
37
38        if ( $noticeId ) {
39            // Return all the banners not already assigned to the current campaign
40            return [
41                'tables' => [
42                    'assignments' => 'cn_assignments',
43                    'templates' => 'cn_templates',
44                ],
45
46                'fields' => [
47                    'templates.tmp_name',
48                    'templates.tmp_id',
49                ],
50
51                'conds' => [
52                    'assignments.tmp_id' => null,
53                    $dbr->expr( 'tmp_name', IExpression::LIKE, new LikeValue( ...$likeArray ) ),
54                    'templates.tmp_is_template' => 0,
55                ],
56
57                'join_conds' => [
58                    'assignments' => [
59                        'LEFT JOIN',
60                        [
61                            "assignments.tmp_id = templates.tmp_id ",
62                            "assignments.not_id" => $noticeId
63                        ]
64                    ]
65                ]
66            ];
67        } else {
68            // Return all the banners in the database
69            return [
70                'tables' => [ 'templates' => 'cn_templates' ],
71                'fields' => [ 'templates.tmp_name', 'templates.tmp_id' ],
72                'conds' => [
73                    $dbr->expr( 'templates.tmp_name', IExpression::LIKE, new LikeValue( ...$likeArray ) ),
74                    'templates.tmp_is_template' => 0,
75                ],
76            ];
77        }
78    }
79
80    /**
81     * Generate the content of each table row (1 row = 1 banner)
82     * @param stdClass $row
83     * @return string HTML
84     */
85    public function formatRow( $row ) {
86        // Begin banner row
87        $htmlOut = Html::openElement( 'tr' );
88
89        if ( $this->editable ) {
90            // Add box
91            $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top' ],
92                Html::check( 'addTemplates[]', false, [ 'value' => $row->tmp_name ] )
93            );
94
95            // Bucket
96            $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top' ],
97                $this->bucketDropdown( $row->tmp_name )
98            );
99
100            // Weight select
101            $options = Html::listDropdownOptions(
102                CentralNotice::dropdownList( $this->msg( 'centralnotice-weight' )->text(), range( 0, 100, 5 ) ),
103                [ 'other' => '' ]
104            );
105            $xmlSelect = new XmlSelect( "weight[$row->tmp_id]", "weight[$row->tmp_id]", '25' );
106            $xmlSelect->addOptions( $options );
107            $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top', 'class' => 'cn-weight' ],
108                $xmlSelect->getHTML()
109            );
110        }
111
112        // Render banner row.
113        $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top' ],
114            BannerRenderer::linkToBanner( $row->tmp_name )
115        );
116
117        // End banner row
118        $htmlOut .= Html::closeElement( 'tr' );
119
120        return $htmlOut;
121    }
122
123    /**
124     * Specify table headers
125     *
126     * @return string
127     */
128    public function getStartBody() {
129        $htmlOut = '';
130        $htmlOut .= Html::openElement( 'table', [ 'cellpadding' => 9 ] );
131        $htmlOut .= Html::openElement( 'tr' );
132        if ( $this->editable ) {
133            $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'width' => '5%' ],
134                $this->msg( "centralnotice-add" )->text()
135            );
136            $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'width' => '5%' ],
137                $this->msg( 'centralnotice-bucket' )->text()
138            );
139            $htmlOut .= Html::element( 'th',
140                [ 'align' => 'left', 'width' => '5%', 'class' => 'cn-weight' ],
141                $this->msg( 'centralnotice-weight' )->text()
142            );
143        }
144        $htmlOut .= Html::element( 'th', [ 'align' => 'left' ],
145            $this->msg( 'centralnotice-templates' )->text()
146        );
147        $htmlOut .= Html::closeElement( 'tr' );
148        return $htmlOut;
149    }
150
151    /**
152     * Close table
153     *
154     * @return string
155     */
156    public function getEndBody() {
157        return Html::closeElement( 'table' );
158    }
159
160    private function bucketDropdown( string $bannerName ): string {
161        global $wgNoticeNumberOfBuckets;
162
163        $html = '';
164        foreach ( range( 0, $wgNoticeNumberOfBuckets - 1 ) as $value ) {
165            $html .= Html::element(
166                'option',
167                [ 'value' => $value ],
168                chr( $value + ord( 'A' ) )
169            );
170        }
171
172        return Html::rawElement( 'select', [
173            'name' => "bucket-{$bannerName}",
174            // class should coordinate with CentralNotice::bucketDropdown()
175            'class' => 'bucketSelector',
176        ], $html );
177    }
178}