Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 83 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
| CNBannerPager | |
0.00% |
0 / 83 |
|
0.00% |
0 / 7 |
650 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
| getNavigationBar | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
| getQueryInfo | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
| getIndexField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| formatRow | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
90 | |||
| getBody | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
56 | |||
| getDefaultQuery | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | // FIXME Unused? See T161907 |
| 4 | // It's not unused, see Special:CentralNoticeBanners. Probably needs to be |
| 5 | // merged with TemplatePager. |
| 6 | |
| 7 | use MediaWiki\HTMLForm\Field\HTMLInfoField; |
| 8 | use MediaWiki\Pager\ReverseChronologicalPager; |
| 9 | use Wikimedia\Rdbms\IExpression; |
| 10 | use Wikimedia\Rdbms\LikeValue; |
| 11 | |
| 12 | class CNBannerPager extends ReverseChronologicalPager { |
| 13 | |
| 14 | /** |
| 15 | * @param SpecialCentralNoticeBanners $hostSpecialPage the page on which we appear |
| 16 | * @param string|null $formSection 'Section' attribute to apply to the banner elements generated |
| 17 | * @param array[] $prependPrototypes HTMLFormFields to add to the results before every banner entry |
| 18 | * @param array[] $appendPrototypes HTMLFormFields to add to the results after every banner entry |
| 19 | * @param string $bannerFilter Space separated strings to filter banner titles on |
| 20 | * @param bool $editable True if the form is to be created with editable elements |
| 21 | */ |
| 22 | public function __construct( |
| 23 | private readonly SpecialCentralNoticeBanners $hostSpecialPage, |
| 24 | private readonly ?string $formSection = null, |
| 25 | private readonly array $prependPrototypes = [], |
| 26 | private readonly array $appendPrototypes = [], |
| 27 | private readonly string $bannerFilter = '', |
| 28 | private readonly bool $editable = false, |
| 29 | ) { |
| 30 | // Set database before parent constructor to avoid setting it there |
| 31 | $this->mDb = CNDatabase::getReplicaDb(); |
| 32 | |
| 33 | parent::__construct(); |
| 34 | |
| 35 | // Override paging defaults |
| 36 | [ $this->mLimit, $this->mOffset ] = $this->mRequest->getLimitOffsetForUser( |
| 37 | $this->getUser(), |
| 38 | 20, |
| 39 | '' |
| 40 | ); |
| 41 | $this->mLimitsShown = [ 20, 50, 100 ]; |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * @inheritDoc |
| 46 | * @suppress PhanTypeMismatchDimAssignment |
| 47 | */ |
| 48 | public function getNavigationBar() { |
| 49 | if ( $this->mNavigationBar !== null ) { |
| 50 | return $this->mNavigationBar; |
| 51 | } |
| 52 | |
| 53 | // Sets mNavigation bar with the default text which we will then wrap |
| 54 | parent::getNavigationBar(); |
| 55 | |
| 56 | // @phan-suppress-next-line PhanTypeMismatchPropertyProbablyReal |
| 57 | $this->mNavigationBar = [ |
| 58 | 'class' => HTMLBannerPagerNavigation::class, |
| 59 | 'value' => $this->mNavigationBar |
| 60 | ]; |
| 61 | |
| 62 | if ( $this->formSection ) { |
| 63 | // @phan-suppress-next-line PhanTypeMismatchPropertyProbablyReal |
| 64 | $this->mNavigationBar['section'] = $this->formSection; |
| 65 | } |
| 66 | |
| 67 | // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal |
| 68 | return $this->mNavigationBar; |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * Set the database query to retrieve all the banners in the database |
| 73 | * |
| 74 | * @return array of query settings |
| 75 | */ |
| 76 | public function getQueryInfo() { |
| 77 | // When the filter comes in it is space delimited, so break that... |
| 78 | $likeArray = preg_split( '/\s/', $this->bannerFilter ); |
| 79 | |
| 80 | // ...and then insert all the wildcards between search terms |
| 81 | if ( !$likeArray ) { |
| 82 | $likeArray = [ $this->mDb->anyString() ]; |
| 83 | } else { |
| 84 | $anyStringToken = $this->mDb->anyString(); |
| 85 | $tempArray = [ $anyStringToken ]; |
| 86 | foreach ( $likeArray as $likePart ) { |
| 87 | $tempArray[] = $likePart; |
| 88 | $tempArray[] = $anyStringToken; |
| 89 | } |
| 90 | $likeArray = $tempArray; |
| 91 | } |
| 92 | |
| 93 | return [ |
| 94 | 'tables' => [ 'templates' => 'cn_templates' ], |
| 95 | 'fields' => [ 'templates.tmp_name', 'templates.tmp_id', 'templates.tmp_is_template' ], |
| 96 | 'conds' => [ $this->mDb->expr( 'templates.tmp_name', IExpression::LIKE, new LikeValue( ...$likeArray ) ) ], |
| 97 | ]; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Sort the banner list by tmp_id (generally equals reverse chronological) |
| 102 | * |
| 103 | * @return string |
| 104 | */ |
| 105 | public function getIndexField() { |
| 106 | return 'templates.tmp_id'; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Generate the contents of the table pager; intended to be consumed by the HTMLForm |
| 111 | * |
| 112 | * @param stdClass $row database row |
| 113 | * |
| 114 | * @return array HTMLFormElement classes |
| 115 | * @suppress PhanParamSignatureMismatch |
| 116 | */ |
| 117 | public function formatRow( $row ) { |
| 118 | $retval = []; |
| 119 | |
| 120 | $bannerId = $row->tmp_id; |
| 121 | $bannerName = $row->tmp_name; |
| 122 | |
| 123 | // Add the prepend prototypes |
| 124 | foreach ( $this->prependPrototypes as $prototypeName => $prototypeValues ) { |
| 125 | $retval[ "{$prototypeName}-{$bannerName}" ] = $prototypeValues; |
| 126 | if ( array_key_exists( 'id', $prototypeValues ) ) { |
| 127 | $retval[ "{$prototypeName}-{$bannerId}" ][ 'id' ] .= "-$bannerName"; |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | // Now do the banner |
| 132 | $rowText = BannerRenderer::linkToBanner( $bannerName ); |
| 133 | if ( (bool)$row->tmp_is_template ) { |
| 134 | $rowText = implode( ' ', [ |
| 135 | $rowText, $this->msg( "centralnotice-banner-template-info" )->escaped() |
| 136 | ] ); |
| 137 | } |
| 138 | $retval["cn-banner-list-element-$bannerId"] = [ |
| 139 | 'class' => HTMLInfoField::class, |
| 140 | 'default' => $rowText . " (" . BannerRenderer::getPreviewLink( $bannerName ) . ")", |
| 141 | 'raw' => true, |
| 142 | ]; |
| 143 | if ( $this->formSection ) { |
| 144 | $retval["cn-banner-list-element-$bannerId"]['section'] = $this->formSection; |
| 145 | } |
| 146 | |
| 147 | // Append prototypes |
| 148 | foreach ( $this->appendPrototypes as $prototypeName => $prototypeValues ) { |
| 149 | $retval[ $prototypeName . "-$bannerId" ] = $prototypeValues; |
| 150 | if ( array_key_exists( 'id', $prototypeValues ) ) { |
| 151 | $retval[ $prototypeName . "-$bannerId" ][ 'id' ] .= "-$bannerId"; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // Set the disabled attribute |
| 156 | if ( !$this->editable ) { |
| 157 | foreach ( $retval as &$prototypeValues ) { |
| 158 | $prototypeValues['disabled'] = true; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | return $retval; |
| 163 | } |
| 164 | |
| 165 | /** |
| 166 | * Get the formatted result list. Calls getStartBody(), formatRow() and |
| 167 | * getEndBody(), concatenates the results and returns them. |
| 168 | * |
| 169 | * @return array |
| 170 | * @suppress PhanParamSignatureMismatch |
| 171 | */ |
| 172 | public function getBody() { |
| 173 | if ( !$this->mQueryDone ) { |
| 174 | $this->doQuery(); |
| 175 | } |
| 176 | |
| 177 | if ( $this->mResult->numRows() ) { |
| 178 | # Do any special query batches before display |
| 179 | $this->doBatchLookups(); |
| 180 | } |
| 181 | |
| 182 | # Don't use any extra rows returned by the query |
| 183 | $numRows = min( $this->mResult->numRows(), $this->mLimit ); |
| 184 | |
| 185 | $retval = []; |
| 186 | |
| 187 | if ( $numRows ) { |
| 188 | if ( $this->mIsBackwards ) { |
| 189 | for ( $i = $numRows - 1; $i >= 0; $i-- ) { |
| 190 | $this->mResult->seek( $i ); |
| 191 | $row = $this->mResult->fetchObject(); |
| 192 | $retval += $this->formatRow( $row ); |
| 193 | } |
| 194 | } else { |
| 195 | $this->mResult->seek( 0 ); |
| 196 | for ( $i = 0; $i < $numRows; $i++ ) { |
| 197 | $row = $this->mResult->fetchObject(); |
| 198 | $retval += $this->formatRow( $row ); |
| 199 | } |
| 200 | } |
| 201 | } else { |
| 202 | // TODO: empty value |
| 203 | } |
| 204 | return $retval; |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * @inheritDoc |
| 209 | */ |
| 210 | public function getDefaultQuery() { |
| 211 | parent::getDefaultQuery(); |
| 212 | $filterQuery = $this->hostSpecialPage->getFilterUrlParamAsArray(); |
| 213 | $this->mDefaultQuery = array_merge( $this->mDefaultQuery, $filterQuery ); |
| 214 | return $this->mDefaultQuery; |
| 215 | } |
| 216 | } |