Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 184 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
| CentralNoticeBannerLogPager | |
0.00% |
0 / 184 |
|
0.00% |
0 / 9 |
812 | |
0.00% |
0 / 1 |
| getIndexField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getQueryInfo | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| formatRow | |
0.00% |
0 / 70 |
|
0.00% |
0 / 1 |
56 | |||
| getStartBody | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
2 | |||
| getEndBody | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| showInitialSettings | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
30 | |||
| showChanges | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
12 | |||
| testBooleanBannerChange | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
30 | |||
| testTextBannerChange | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php |
| 2 | |
| 3 | use MediaWiki\Html\Html; |
| 4 | use MediaWiki\SpecialPage\SpecialPage; |
| 5 | use MediaWiki\User\User; |
| 6 | use Wikimedia\Rdbms\SelectQueryBuilder; |
| 7 | |
| 8 | class CentralNoticeBannerLogPager extends CentralNoticeCampaignLogPager { |
| 9 | |
| 10 | /** |
| 11 | * Sort the log list by timestamp |
| 12 | * @return string |
| 13 | */ |
| 14 | public function getIndexField() { |
| 15 | return 'tmplog_timestamp'; |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * Pull log entries from the database |
| 20 | * @return array |
| 21 | */ |
| 22 | public function getQueryInfo() { |
| 23 | return [ |
| 24 | 'tables' => [ 'template_log' => 'cn_template_log' ], |
| 25 | 'fields' => '*', |
| 26 | ]; |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * Generate the content of each table row (1 row = 1 log entry) |
| 31 | * @param stdClass $row |
| 32 | * @return string HTML |
| 33 | */ |
| 34 | public function formatRow( $row ) { |
| 35 | global $wgExtensionAssetsPath; |
| 36 | $lang = $this->getLanguage(); |
| 37 | |
| 38 | // Create a user object so we can pull the name, user page, etc. |
| 39 | $loggedUser = User::newFromId( $row->tmplog_user_id ); |
| 40 | // Create the user page link |
| 41 | $userLink = $this->special->getLinkRenderer()->makeKnownLink( |
| 42 | $loggedUser->getUserPage(), |
| 43 | $loggedUser->getName() |
| 44 | ); |
| 45 | $userTalkLink = $this->special->getLinkRenderer()->makeKnownLink( |
| 46 | $loggedUser->getTalkPage(), |
| 47 | $this->msg( 'centralnotice-talk-link' )->text() |
| 48 | ); |
| 49 | |
| 50 | // Create the banner link |
| 51 | $bannerLink = $this->special->getLinkRenderer()->makeKnownLink( |
| 52 | SpecialPage::getTitleFor( 'CentralNoticeBanners', "edit/{$row->tmplog_template_name}" ), |
| 53 | $row->tmplog_template_name |
| 54 | ); |
| 55 | |
| 56 | // Begin log entry primary row |
| 57 | $htmlOut = Html::openElement( 'tr' ); |
| 58 | |
| 59 | $htmlOut .= Html::openElement( 'td', [ 'valign' => 'top' ] ); |
| 60 | if ( $row->tmplog_action !== 'removed' ) { |
| 61 | $collapsedImg = $this->getLanguage()->isRtl() ? |
| 62 | 'collapsed-rtl.png' : |
| 63 | 'collapsed-ltr.png'; |
| 64 | |
| 65 | $tmplogId = (int)$row->tmplog_id; |
| 66 | $htmlOut .= '<a href="javascript:toggleLogDisplay(\'' . $tmplogId . '\')">' . |
| 67 | '<img src="' . $wgExtensionAssetsPath . '/CentralNotice/resources/images/' . $collapsedImg . '" ' . |
| 68 | 'id="cn-collapsed-' . $tmplogId . '" ' . |
| 69 | 'style="display:block;vertical-align:baseline;"/>' . |
| 70 | '<img src="' . $wgExtensionAssetsPath . '/CentralNotice/resources/images/uncollapsed.png" ' . |
| 71 | 'id="cn-uncollapsed-' . $tmplogId . '" ' . |
| 72 | 'style="display:none;vertical-align:baseline;"/>' . |
| 73 | '</a>'; |
| 74 | } |
| 75 | $htmlOut .= Html::closeElement( 'td' ); |
| 76 | $htmlOut .= Html::element( 'td', [ 'valign' => 'top', 'class' => 'primary' ], |
| 77 | $lang->date( $row->tmplog_timestamp ) . ' ' . $lang->time( $row->tmplog_timestamp ) |
| 78 | ); |
| 79 | $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top', 'class' => 'primary' ], |
| 80 | $this->msg( 'centralnotice-user-links' ) |
| 81 | ->rawParams( $userLink, $userTalkLink ) |
| 82 | ->escaped() |
| 83 | ); |
| 84 | // Give grep a chance to find the usages: |
| 85 | // centralnotice-action-created, centralnotice-action-modified, |
| 86 | // centralnotice-action-removed |
| 87 | $htmlOut .= Html::element( 'td', [ 'valign' => 'top', 'class' => 'primary' ], |
| 88 | $this->msg( 'centralnotice-action-' . $row->tmplog_action )->text() |
| 89 | ); |
| 90 | $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top', 'class' => 'primary' ], |
| 91 | $bannerLink |
| 92 | ); |
| 93 | |
| 94 | $summary = $row->tmplog_comment === null |
| 95 | ? ' ' |
| 96 | : htmlspecialchars( $row->tmplog_comment ); |
| 97 | |
| 98 | $htmlOut .= Html::rawElement( 'td', |
| 99 | [ 'valign' => 'top', 'class' => 'primary-summary' ], |
| 100 | $summary |
| 101 | ); |
| 102 | |
| 103 | $htmlOut .= Html::rawElement( 'td', [], |
| 104 | ' ' |
| 105 | ); |
| 106 | |
| 107 | // End log entry primary row |
| 108 | $htmlOut .= Html::closeElement( 'tr' ); |
| 109 | |
| 110 | if ( $row->tmplog_action !== 'removed' ) { |
| 111 | // Begin log entry secondary row |
| 112 | $htmlOut .= Html::openElement( 'tr', |
| 113 | [ 'id' => 'cn-log-details-' . $tmplogId, 'style' => 'display:none;' ] ); |
| 114 | // @phan-suppress-previous-line PhanPossiblyUndeclaredVariable |
| 115 | |
| 116 | $htmlOut .= Html::rawElement( 'td', [ 'valign' => 'top' ], |
| 117 | // force a table cell in older browsers |
| 118 | ' ' |
| 119 | ); |
| 120 | $htmlOut .= Html::openElement( 'td', [ 'valign' => 'top', 'colspan' => '5' ] ); |
| 121 | if ( $row->tmplog_action === 'created' ) { |
| 122 | $htmlOut .= $this->showInitialSettings( $row ); |
| 123 | } elseif ( $row->tmplog_action === 'modified' ) { |
| 124 | $htmlOut .= $this->showChanges( $row ); |
| 125 | } |
| 126 | $htmlOut .= Html::closeElement( 'td' ); |
| 127 | |
| 128 | // End log entry primary row |
| 129 | $htmlOut .= Html::closeElement( 'tr' ); |
| 130 | } |
| 131 | |
| 132 | return $htmlOut; |
| 133 | } |
| 134 | |
| 135 | /** @inheritDoc */ |
| 136 | public function getStartBody() { |
| 137 | $htmlOut = ''; |
| 138 | $htmlOut .= Html::openElement( 'table', [ 'id' => 'cn-campaign-logs', 'cellpadding' => 3 ] ); |
| 139 | $htmlOut .= Html::openElement( 'tr' ); |
| 140 | $htmlOut .= Html::element( 'th', [ 'style' => 'width: 20px;' ] ); |
| 141 | $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'style' => 'width: 130px;' ], |
| 142 | $this->msg( 'centralnotice-timestamp' )->text() |
| 143 | ); |
| 144 | $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'style' => 'width: 160px;' ], |
| 145 | $this->msg( 'centralnotice-user' )->text() |
| 146 | ); |
| 147 | $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'style' => 'width: 100px;' ], |
| 148 | $this->msg( 'centralnotice-action' )->text() |
| 149 | ); |
| 150 | $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'style' => 'width: 160px;' ], |
| 151 | $this->msg( 'centralnotice-banner' )->text() |
| 152 | ); |
| 153 | $htmlOut .= Html::element( 'th', [ 'align' => 'left', 'style' => 'width: 250px;' ], |
| 154 | $this->msg( 'centralnotice-change-summary-heading' )->text() |
| 155 | ); |
| 156 | $htmlOut .= Html::rawElement( 'td', [], |
| 157 | ' ' |
| 158 | ); |
| 159 | $htmlOut .= Html::closeElement( 'tr' ); |
| 160 | return $htmlOut; |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * Close table |
| 165 | * @return string |
| 166 | */ |
| 167 | public function getEndBody() { |
| 168 | return Html::closeElement( 'table' ); |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * @param stdClass $row |
| 173 | * @return string |
| 174 | */ |
| 175 | public function showInitialSettings( $row ) { |
| 176 | $details = ''; |
| 177 | $details .= $this->msg( |
| 178 | 'centralnotice-log-label', |
| 179 | $this->msg( 'centralnotice-anon' )->text(), |
| 180 | ( $row->tmplog_end_anon ? 'on' : 'off' ) |
| 181 | )->parse() . "<br/>"; |
| 182 | $details .= $this->msg( |
| 183 | 'centralnotice-log-label', |
| 184 | $this->msg( 'centralnotice-account' )->text(), |
| 185 | ( $row->tmplog_end_account ? 'on' : 'off' ) |
| 186 | )->parse() . "<br/>"; |
| 187 | $details .= $this->msg( |
| 188 | 'centralnotice-log-label', |
| 189 | $this->msg( 'centralnotice-category' )->text(), |
| 190 | wfEscapeWikiText( $row->tmplog_end_category ) |
| 191 | )->parse() . "<br/>"; |
| 192 | |
| 193 | // Autolink/landing pages feature has been removed, but we might as |
| 194 | // well show any info about it in the logs. |
| 195 | $details .= $this->msg( |
| 196 | 'centralnotice-log-label', |
| 197 | $this->msg( 'centralnotice-autolink' )->text(), |
| 198 | ( $row->tmplog_end_autolink ? 'on' : 'off' ) |
| 199 | )->parse() . "<br/>"; |
| 200 | if ( $row->tmplog_end_landingpages ) { |
| 201 | $details .= $this->msg( |
| 202 | 'centralnotice-log-label', |
| 203 | $this->msg( 'centralnotice-landingpages' )->text(), |
| 204 | wfEscapeWikiText( $row->tmplog_end_landingpages ) |
| 205 | )->parse() . "<br/>"; |
| 206 | } |
| 207 | $details .= $this->msg( |
| 208 | 'centralnotice-log-label', |
| 209 | $this->msg( 'centralnotice-devices' )->text(), |
| 210 | wfEscapeWikiText( $row->tmplog_end_devices ) |
| 211 | )->parse() . "<br/>"; |
| 212 | return $details; |
| 213 | } |
| 214 | |
| 215 | /** |
| 216 | * @param stdClass $newrow |
| 217 | * @return string |
| 218 | */ |
| 219 | public function showChanges( $newrow ) { |
| 220 | $oldrow = false; |
| 221 | if ( $newrow->tmplog_action === 'modified' ) { |
| 222 | $db = CNDatabase::getReplicaDb(); |
| 223 | $tmplogId = (int)$newrow->tmplog_id; |
| 224 | $oldrow = $db->newSelectQueryBuilder() |
| 225 | ->select( '*' ) |
| 226 | ->from( 'cn_template_log' ) |
| 227 | ->where( [ |
| 228 | 'tmplog_template_id' => $newrow->tmplog_template_id, |
| 229 | $db->expr( 'tmplog_id', '<', $tmplogId ), |
| 230 | ] ) |
| 231 | ->orderBy( 'tmplog_id', SelectQueryBuilder::SORT_DESC ) |
| 232 | ->caller( __METHOD__ ) |
| 233 | ->fetchRow(); |
| 234 | } |
| 235 | |
| 236 | $details = $this->testBooleanBannerChange( 'anon', $newrow, $oldrow ); |
| 237 | $details .= $this->testBooleanBannerChange( 'account', $newrow, $oldrow ); |
| 238 | $details .= $this->testTextBannerChange( 'category', $newrow, $oldrow ); |
| 239 | $details .= $this->testBooleanBannerChange( 'autolink', $newrow, $oldrow ); |
| 240 | $details .= $this->testTextBannerChange( 'landingpages', $newrow, $oldrow ); |
| 241 | $details .= $this->testTextBannerChange( 'controller_mixin', $newrow, $oldrow ); |
| 242 | $details .= $this->testTextBannerChange( 'prioritylangs', $newrow, $oldrow ); |
| 243 | $details .= $this->testTextBannerChange( 'devices', $newrow, $oldrow ); |
| 244 | if ( $newrow->tmplog_content_change ) { |
| 245 | // Show changes to banner content |
| 246 | $details .= $this->msg( |
| 247 | 'centralnotice-log-label', |
| 248 | $this->msg( 'centralnotice-banner-content' )->text(), |
| 249 | $this->msg( 'centralnotice-banner-content-changed' )->text() |
| 250 | )->parse() . "<br/>"; |
| 251 | } |
| 252 | return $details; |
| 253 | } |
| 254 | |
| 255 | /** |
| 256 | * @param string $param |
| 257 | * @param stdClass $newrow |
| 258 | * @param stdClass $oldrow |
| 259 | * @return string |
| 260 | */ |
| 261 | private function testBooleanBannerChange( $param, $newrow, $oldrow ) { |
| 262 | $result = ''; |
| 263 | $endField = 'tmplog_end_' . $param; |
| 264 | |
| 265 | $oldval = ( $oldrow ) ? $oldrow->$endField : 0; |
| 266 | if ( $oldval !== $newrow->$endField ) { |
| 267 | // The following messages are generated here: |
| 268 | // * centralnotice-anon |
| 269 | // * centralnotice-account |
| 270 | // * centralnotice-autolink |
| 271 | $result .= $this->msg( |
| 272 | 'centralnotice-log-label', |
| 273 | $this->msg( 'centralnotice-' . $param )->text(), |
| 274 | $this->msg( |
| 275 | 'centralnotice-changed', |
| 276 | ( $oldval |
| 277 | ? $this->msg( 'centralnotice-on' )->text() |
| 278 | : $this->msg( 'centralnotice-off' )->text() ), |
| 279 | ( $newrow->$endField |
| 280 | ? $this->msg( 'centralnotice-on' )->text() |
| 281 | : $this->msg( 'centralnotice-off' )->text() ) |
| 282 | )->text() |
| 283 | )->parse() . "<br/>"; |
| 284 | } |
| 285 | return $result; |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * @param string $param |
| 290 | * @param stdClass $newrow |
| 291 | * @param stdClass $oldrow |
| 292 | * @return string |
| 293 | */ |
| 294 | private function testTextBannerChange( $param, $newrow, $oldrow ) { |
| 295 | $endField = 'tmplog_end_' . $param; |
| 296 | |
| 297 | $oldval = ( ( $oldrow ) ? $oldrow->$endField : '' ) ?: ''; |
| 298 | $newval = ( $newrow->$endField ) ?: ''; |
| 299 | |
| 300 | return $this->testTextChange( $param, $newval, $oldval ); |
| 301 | } |
| 302 | } |