r71004 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r71003‎ | r71004 | r71005 >
Date:01:52, 13 August 2010
Author:kaldari
Status:resolved (Comments)
Tags:
Comment:
allow control of whether banners are displayed to anon and/or logged in users
Modified paths:
  • /trunk/extensions/CentralNotice/CentralNotice.db.php (modified) (history)
  • /trunk/extensions/CentralNotice/CentralNotice.php (modified) (history)
  • /trunk/extensions/CentralNotice/SpecialCentralNotice.php (modified) (history)
  • /trunk/extensions/CentralNotice/SpecialNoticeTemplate.php (modified) (history)
  • /trunk/extensions/CentralNotice/SpecialNoticeText.php (modified) (history)
  • /trunk/extensions/CentralNotice/patches/patch-notice_preferred.sql (modified) (history)
  • /trunk/extensions/CentralNotice/patches/patch-template_settings.sql (added) (history)

Diff [purge]

Index: trunk/extensions/CentralNotice/CentralNotice.php
@@ -158,6 +158,7 @@
159159 $wgExtNewTables[] = array( 'cn_notices', $base . '/CentralNotice.sql' );
160160 $wgExtNewFields[] = array( 'cn_notices', 'not_preferred', $base . '/patches/patch-notice_preferred.sql' );
161161 $wgExtNewTables[] = array( 'cn_notice_languages', $base . '/patches/patch-notice_languages.sql' );
 162+ $wgExtNewFields[] = array( 'cn_templates', 'tmp_display_anon', $base . '/patches/patch-template_settings.sql' );
162163 }
163164 return true;
164165 }
Index: trunk/extensions/CentralNotice/SpecialCentralNotice.php
@@ -1013,6 +1013,7 @@
10141014
10151015 /**
10161016 * Build a list of all the banners assigned to a campaign
 1017+ * @return An array of template names
10171018 */
10181019 function selectTemplatesAssigned ( $notice ) {
10191020 $dbr = wfGetDB( DB_SLAVE );
@@ -1041,8 +1042,10 @@
10421043 }
10431044
10441045 /**
1045 - * Lookup function for active campaigns under a given language and project
1046 - * @return An array of running campaign names with associated banner weights
 1046+ * Lookup function for active banners under a given language and project. This function is
 1047+ * called by SpecialNoticeText::getJsOutput() in order to build the static Javascript files for
 1048+ * each project.
 1049+ * @return A 2D array of running banners with associated weights and settings
10471050 */
10481051 static function selectNoticeTemplates( $project, $language ) {
10491052 $dbr = wfGetDB( DB_SLAVE );
@@ -1056,7 +1059,9 @@
10571060 ),
10581061 array(
10591062 'tmp_name',
1060 - 'SUM(tmp_weight) AS total_weight'
 1063+ 'SUM(tmp_weight) AS total_weight',
 1064+ 'tmp_display_anon',
 1065+ 'tmp_display_account'
10611066 ),
10621067 array (
10631068 "not_start <= $encTimestamp",
@@ -1073,13 +1078,16 @@
10741079 'GROUP BY' => 'tmp_name'
10751080 )
10761081 );
1077 - $templateWeights = array();
 1082+ $templates = array();
10781083 foreach ( $res as $row ) {
1079 - $name = $row->tmp_name;
1080 - $weight = intval( $row->total_weight );
1081 - $templateWeights[$name] = $weight;
 1084+ $template = array();
 1085+ $template['name'] = $row->tmp_name;
 1086+ $template['weight'] = intval( $row->total_weight );
 1087+ $template['display_anon'] = intval( $row->tmp_display_anon );
 1088+ $template['display_account'] = intval( $row->tmp_display_account );
 1089+ $templates[] = $template;
10821090 }
1083 - return $templateWeights;
 1091+ return $templates;
10841092 }
10851093
10861094 function addNotice( $noticeName, $enabled, $start, $project_name, $project_languages ) {
Index: trunk/extensions/CentralNotice/patches/patch-template_settings.sql
@@ -0,0 +1,7 @@
 2+-- Update to support controlling whether banners are displayed to anon and/or logged in users.
 3+-- Two flags are stored in the database for each banner, one indicating whether or not the banner
 4+-- is displayed to anonymous users, the other indicating whether or not the banner is displayed
 5+-- to logged in users.
 6+
 7+ALTER TABLE /*$wgDBprefix*/cn_templates ADD `tmp_display_anon` BOOLEAN NOT NULL DEFAULT 1,
 8+ ADD `tmp_display_account` BOOLEAN NOT NULL DEFAULT 1;
Index: trunk/extensions/CentralNotice/patches/patch-notice_preferred.sql
@@ -3,4 +3,4 @@
44 -- overlap. Use case is to be able to use one all language and projects notice
55 -- and have it superceded by a specific one for en wikipedia.
66
7 -ALTER TABLE cn_notices ADD COLUMN not_preferred bool NOT NULL default '0';
 7+ALTER TABLE /*$wgDBprefix*/cn_notices ADD COLUMN not_preferred bool NOT NULL default '0';
Index: trunk/extensions/CentralNotice/SpecialNoticeTemplate.php
@@ -72,16 +72,48 @@
7373 // Handle adding banner
7474 // FIXME: getText()? weak comparison
7575 if ( $wgRequest->getVal( 'wpMethod' ) == 'addTemplate' ) {
 76+
 77+ // Handle "Display to anonymous users" checkbox
 78+ $displayAnon = 0;
 79+ if ( $wgRequest->getVal( 'displayAnon' ) ) {
 80+ $displayAnon = $wgRequest->getVal( 'displayAnon' );
 81+ }
 82+
 83+ // Handle "Display to logged in users" checkbox
 84+ $displayAccount = 0;
 85+ if ( $wgRequest->getVal( 'displayAccount' ) ) {
 86+ $displayAccount = $wgRequest->getVal( 'displayAccount' );
 87+ }
 88+
7689 $this->addTemplate(
7790 $wgRequest->getVal( 'templateName' ),
78 - $wgRequest->getVal( 'templateBody' )
 91+ $wgRequest->getVal( 'templateBody' ),
 92+ $displayAnon,
 93+ $displayAccount
7994 );
8095 $sub = 'view';
8196 }
 97+
 98+ // Handle editing banner
8299 if ( $wgRequest->getVal( 'wpMethod' ) == 'editTemplate' ) {
 100+
 101+ // Handle "Display to anonymous users" checkbox
 102+ $displayAnon = 0;
 103+ if ( $wgRequest->getVal( 'displayAnon' ) ) {
 104+ $displayAnon = $wgRequest->getVal( 'displayAnon' );
 105+ }
 106+
 107+ // Handle "Display to logged in users" checkbox
 108+ $displayAccount = 0;
 109+ if ( $wgRequest->getVal( 'displayAccount' ) ) {
 110+ $displayAccount = $wgRequest->getVal( 'displayAccount' );
 111+ }
 112+
83113 $this->editTemplate(
84114 $wgRequest->getVal( 'template' ),
85 - $wgRequest->getVal( 'templateBody' )
 115+ $wgRequest->getVal( 'templateBody' ),
 116+ $displayAnon,
 117+ $displayAccount
86118 );
87119 $sub = 'view';
88120 }
@@ -194,6 +226,15 @@
195227 $htmlOut .= Xml::tags( 'p', null,
196228 Xml::inputLabel( wfMsg( 'centralnotice-banner-name' ) . ":", 'templateName', 'templateName', 25 )
197229 );
 230+
 231+ $htmlOut .= Xml::openElement( 'p', null );
 232+ $htmlOut .= wfMsg( 'centralnotice-banner-display' );
 233+ $htmlOut .= Xml::check( 'displayAnon', true, array( 'id' => 'displayAnon' ) );
 234+ $htmlOut .= Xml::label( wfMsg( 'centralnotice-banner-anonymous' ), 'displayAnon' );
 235+ $htmlOut .= Xml::check( 'displayAccount', true, array( 'id' => 'displayAccount' ) );
 236+ $htmlOut .= Xml::label( wfMsg( 'centralnotice-banner-logged-in' ), 'displayAccount' );
 237+ $htmlOut .= Xml::closeElement( 'p' );
 238+
198239 $htmlOut .= Xml::fieldset( wfMsg( 'centralnotice-banner' ) );
199240 $htmlOut .= wfMsg( 'centralnotice-edit-template-summary' );
200241 $buttons = array();
@@ -231,8 +272,10 @@
232273
233274 if ( $this->editable ) {
234275 $readonly = array();
 276+ $disabled = array();
235277 } else {
236278 $readonly = array( 'readonly' => 'readonly' );
 279+ $disabled = array( 'disabled' => 'disabled' );
237280 }
238281
239282 // Get user's language
@@ -241,6 +284,17 @@
242285 // Get current banner
243286 $currentTemplate = $wgRequest->getText( 'template' );
244287
 288+ // Pull banner settings from database
 289+ $dbr = wfGetDB( DB_SLAVE );
 290+ $row = $dbr->selectRow( 'cn_templates',
 291+ array(
 292+ 'tmp_display_anon',
 293+ 'tmp_display_account'
 294+ ),
 295+ array( 'tmp_name' => $currentTemplate ),
 296+ __METHOD__
 297+ );
 298+
245299 // Begin building HTML
246300 $htmlOut = '';
247301
@@ -397,6 +451,18 @@
398452 $htmlOut .= Xml::openElement( 'form', array( 'method' => 'post' ) );
399453 $htmlOut .= Xml::hidden( 'wpMethod', 'editTemplate' );
400454 }
 455+
 456+ // Show banner settings
 457+ $htmlOut .= Xml::fieldset( 'Settings' );
 458+ $htmlOut .= Xml::openElement( 'p', null );
 459+ $htmlOut .= wfMsg( 'centralnotice-banner-display' );
 460+ $htmlOut .= Xml::check( 'displayAnon', ( $row->tmp_display_anon == 1 ), wfArrayMerge( $disabled, array( 'id' => 'displayAnon' ) ) );
 461+ $htmlOut .= Xml::label( wfMsg( 'centralnotice-banner-anonymous' ), 'displayAnon' );
 462+ $htmlOut .= Xml::check( 'displayAccount', ( $row->tmp_display_account == 1 ), wfArrayMerge( $disabled, array( 'id' => 'displayAccount' ) ) );
 463+ $htmlOut .= Xml::label( wfMsg( 'centralnotice-banner-logged-in' ), 'displayAccount' );
 464+ $htmlOut .= Xml::closeElement( 'p' );
 465+ $htmlOut .= Xml::closeElement( 'fieldset' );
 466+
401467 $htmlOut .= Xml::fieldset( wfMsg( 'centralnotice-edit-template' ) );
402468 $htmlOut .= wfMsg( 'centralnotice-edit-template-summary' );
403469 $buttons = array();
@@ -552,7 +618,7 @@
553619 /**
554620 * Create a new banner
555621 */
556 - private function addTemplate ( $name, $body ) {
 622+ private function addTemplate( $name, $body, $displayAnon, $displayAccount ) {
557623 global $wgOut;
558624
559625 if ( $body == '' || $name == '' ) {
@@ -577,9 +643,12 @@
578644 } else {
579645 $dbw = wfGetDB( DB_MASTER );
580646 $dbw->begin();
581 - $res = $dbw->insert(
582 - 'cn_templates',
583 - array( 'tmp_name' => $name ),
 647+ $res = $dbw->insert( 'cn_templates',
 648+ array(
 649+ 'tmp_name' => $name,
 650+ 'tmp_display_anon' => $displayAnon,
 651+ 'tmp_display_account' => $displayAccount
 652+ ),
584653 __METHOD__
585654 );
586655 $dbw->commit();
@@ -596,7 +665,7 @@
597666 /**
598667 * Update a banner
599668 */
600 - private function editTemplate ( $name, $body ) {
 669+ private function editTemplate( $name, $body, $displayAnon, $displayAccount ) {
601670 global $wgOut;
602671
603672 if ( $body == '' || $name == '' ) {
@@ -610,7 +679,18 @@
611680 __METHOD__
612681 );
613682
614 - if ( $dbr->numRows( $res ) > 0 ) {
 683+ if ( $dbr->numRows( $res ) == 1 ) {
 684+ $dbw = wfGetDB( DB_MASTER );
 685+ $dbw->begin();
 686+ $res = $dbw->update( 'cn_templates',
 687+ array(
 688+ 'tmp_display_anon' => $displayAnon,
 689+ 'tmp_display_account' => $displayAccount
 690+ ),
 691+ array( 'tmp_name' => $name )
 692+ );
 693+ $dbw->commit();
 694+
615695 // Perhaps these should move into the db as blob
616696 $article = new Article(
617697 Title::newFromText( "centralnotice-template-{$name}", NS_MEDIAWIKI )
@@ -624,19 +704,35 @@
625705 * Copy all the data from one banner to another
626706 */
627707 public function cloneTemplate( $source, $dest ) {
 708+
628709 // Reset the timer as updates on meta take a long time
629710 set_time_limit( 300 );
 711+
630712 // Pull all possible langs
631713 $langs = $this->getTranslations( $source );
632714
633715 // Normalize name
634716 $dest = ereg_replace( '[^A-Za-z0-9\_]', '', $dest );
 717+
 718+ // Pull banner settings from database
 719+ $dbr = wfGetDB( DB_SLAVE );
 720+ $row = $dbr->selectRow( 'cn_templates',
 721+ array(
 722+ 'tmp_display_anon',
 723+ 'tmp_display_account'
 724+ ),
 725+ array( 'tmp_name' => $source ),
 726+ __METHOD__
 727+ );
 728+ $displayAnon = $row->tmp_display_anon;
 729+ $displayAccount = $row->tmp_display_account;
635730
636 - // Pull text and respect any inc: markup
 731+ // Pull banner text and respect any inc: markup
637732 $bodyPage = Title::newFromText( "Centralnotice-template-{$source}", NS_MEDIAWIKI );
638733 $template_body = Revision::newFromTitle( $bodyPage )->getText();
639734
640 - if ( $this->addTemplate( $dest, $template_body ) ) {
 735+ // Create new banner
 736+ if ( $this->addTemplate( $dest, $template_body, $displayAnon, $displayAccount ) ) {
641737
642738 // Populate the fields
643739 foreach ( $langs as $lang => $fields ) {
Index: trunk/extensions/CentralNotice/CentralNotice.db.php
@@ -79,7 +79,7 @@
8080 }
8181
8282 /*
83 - * Given a notice return all templates bound to it
 83+ * Given a notice return all banners bound to it
8484 */
8585 public function selectTemplatesAssigned( $notice ) {
8686 $dbr = wfGetDB( DB_SLAVE );
@@ -92,8 +92,10 @@
9393 'cn_templates'
9494 ),
9595 array(
96 - 'cn_templates.tmp_name',
 96+ 'tmp_name',
9797 'SUM(tmp_weight) AS total_weight',
 98+ 'tmp_display_anon',
 99+ 'tmp_display_account'
98100 ),
99101 array(
100102 'cn_notices.not_name' => $notice,
@@ -105,13 +107,16 @@
106108 'GROUP BY' => 'tmp_name'
107109 )
108110 );
109 - $templateWeights = array();
 111+ $templates = array();
110112 foreach ( $res as $row ) {
111 - $name = $row->tmp_name;
112 - $weight = intval( $row->total_weight );
113 - $templateWeights[$name] = $weight;
 113+ $template = array();
 114+ $template['name'] = $row->tmp_name;
 115+ $template['weight'] = intval( $row->total_weight );
 116+ $template['display_anon'] = intval( $row->tmp_display_anon );
 117+ $template['display_account'] = intval( $row->tmp_display_account );
 118+ $templates[] = $template;
114119 }
115 - return $templateWeights;
 120+ return $templates;
116121 }
117122
118123 public function updatePreferred( $notice, $preferred ) {
Index: trunk/extensions/CentralNotice/SpecialNoticeText.php
@@ -1,5 +1,8 @@
22 <?php
33
 4+/**
 5+ * Generates content for static Javascript files
 6+ */
47 class SpecialNoticeText extends NoticePage {
58 var $project = 'wikipedia';
69 var $language = 'en';
@@ -21,6 +24,9 @@
2225 return 86400 * 7;
2326 }
2427
 28+ /**
 29+ * Given a project key, generate the body for a static Javascript file
 30+ */
2531 function getJsOutput( $par ) {
2632
2733 // Break $par into separate parameters and assign to $this->project and $this->language
@@ -60,7 +66,18 @@
6167 $templates = CentralNotice::selectNoticeTemplates( $this->project, $this->language );
6268 }
6369
64 - $templateNames = array_keys( $templates );
 70+ // Slice the columns of the $templates array into separate arrays.
 71+ // This is required due to how pickTemplate() currently works.
 72+ $templateNames = array();
 73+ $templateWeights = array();
 74+ $templateDisplayAnons = array();
 75+ $templateDisplayAccounts = array();
 76+ foreach ( $templates as $template ) {
 77+ $templateNames[] = $template['name'];
 78+ $templateWeights[] = $template['weight'];
 79+ $templateDisplayAnons[] = $template['display_anon'];
 80+ $templateDisplayAccounts[] = $template['display_account'];
 81+ }
6582
6683 $templateTexts = array_map(
6784 array( $this, 'getHtmlNotice' ),
@@ -69,23 +86,23 @@
7087 if ( preg_grep( "/&lt;centralnotice-template-\w{1,}&gt;\z/", $templateTexts ) ) {
7188 return false; // Bailing out if we have a failed cache lookup
7289 }
73 -
74 - $weights = array_values( $templates );
75 -
 90+
7691 return
7792 $this->getScriptFunctions() .
7893 $this->getToggleScripts() .
7994 'wgNotice=pickTemplate(' .
8095 Xml::encodeJsVar( $templateTexts ) .
8196 "," .
82 - Xml::encodeJsVar( $weights ) .
 97+ Xml::encodeJsVar( $templateWeights ) .
 98+ "," .
 99+ Xml::encodeJsVar( $templateDisplayAnons ) .
 100+ "," .
 101+ Xml::encodeJsVar( $templateDisplayAccounts ) .
83102 ");\n" .
84103 "if (wgNotice != '')\n" .
85104 "wgNotice='<div id=\"centralNotice\" class=\"' + " .
86105 "(wgNoticeToggleState ? 'expanded' : 'collapsed') + " .
87 - "' ' + " .
88 - "(wgUserName ? 'usernotice' : 'anonnotice' ) + " .
89 - "'\">' + wgNotice+'</div>';\n";
 106+ "'\">' + wgNotice+'</div>';\n";
90107 }
91108
92109 function getHtmlNotice( $noticeName ) {
@@ -142,25 +159,27 @@
143160 var work='hidesnmessage='+state+'; expires=' + e.toGMTString() + '; path=/';
144161 document.cookie = work;
145162 }
146 -function pickTemplate(templates, weights) {
 163+function pickTemplate(templates, weights, displayAnons, displayAccounts) {
147164 var weightedTemplates = new Array();
148165 var currentTemplate = 0;
149166 var totalWeight = 0;
150167
151168 if (templates.length == 0)
152169 return '';
153 -
 170+
154171 while (currentTemplate < templates.length) {
155 - totalWeight += weights[currentTemplate];
156 - for (i=0; i<weights[currentTemplate]; i++) {
157 - weightedTemplates[weightedTemplates.length] = templates[currentTemplate];
 172+ if ((wgUserName && displayAccounts[currentTemplate]) || (!wgUserName && displayAnons[currentTemplate])) {
 173+ totalWeight += weights[currentTemplate];
 174+ for (i=0; i<weights[currentTemplate]; i++) {
 175+ weightedTemplates[weightedTemplates.length] = templates[currentTemplate];
 176+ }
158177 }
159178 currentTemplate++;
160179 }
161 -
 180+
162181 if (totalWeight == 0)
163182 return '';
164 -
 183+
165184 var randomnumber=Math.floor(Math.random()*totalWeight);
166185 return weightedTemplates[randomnumber];
167186 }\n\n";

Follow-up revisions

RevisionCommit summaryAuthorDate
r71222forgot to update main SQL file for r71004, cleaning up SQL formattingkaldari00:08, 18 August 2010
r71581unreinventing getBool per r71004 commentkaldari20:43, 24 August 2010
r71582scoping Javascript var per comment at r71004kaldari20:50, 24 August 2010
r71586localizing 'Settings' per comment at r71004kaldari21:10, 24 August 2010

Comments

#Comment by Catrope (talk | contribs)   00:54, 24 August 2010
+				$displayAnon = 0;
+				if ( $wgRequest->getVal( 'displayAnon' ) ) {
+					$displayAnon = $wgRequest->getVal( 'displayAnon' );
+				}

You're reinventing $wgRequest->getBool() here.

+		$htmlOut .= Xml::fieldset( 'Settings' );

Needs i18n.

+			for (i=0; i<weights[currentTemplate]; i++) {

Needs to say var i = 0; so as to not pollute the global scope.

#Comment by Kaldari (talk | contribs)   21:11, 24 August 2010

These issues are fixed by r71581, r71586, and r71582 respectively.

#Comment by Tim Starling (talk | contribs)   02:03, 26 August 2010

I think adding two extra parameters to several functions was not the best way to do this, and as a result, the code here is barely passable. The data structure returned by selectTemplatesAssigned() is good, and you could easily have used it to reduce the number of formal parameters in addTemplate(), editTemplate(), and the JavaScript function pickTemplate(). The excuse given in the comment "This is required due to how pickTemplate() currently works" is not particularly convincing since you are substantially changing how pickTemplate() works, and you could have changed this while you were at it.

I'm marking this resolved.

#Comment by Kaldari (talk | contribs)   03:14, 26 August 2010

All of the pickTemplates functionality is going to be redone from scratch next month. Just need to get this feature usable in the meantime (for tomorrow's test campaign). Otherwise, I agree with you completely :)

#Comment by Catrope (talk | contribs)   02:21, 26 August 2010

Yes, the way this currently works is totally weird, but right now we just want to get this deployed by noon on Thursday. Then for phase 2 Ryan is planning to overhaul the JS (or have Adam do so), among a lot of other things.

Status & tagging log