Index: trunk/extensions/ContributionReporting/ContributionReporting.php |
— | — | @@ -45,7 +45,6 @@ |
46 | 46 | $wgAutoloadClasses['SpecialYearlyTotal'] = $dir . 'YearlyTotal_body.php'; |
47 | 47 | $wgAutoloadClasses['DisabledNotice'] = $dir . 'DisabledNotice_body.php'; |
48 | 48 | |
49 | | -/* |
50 | 49 | $wgSpecialPages['ContributionHistory'] = 'ContributionHistory'; |
51 | 50 | $wgSpecialPages['ContributionTotal'] = 'ContributionTotal'; |
52 | 51 | $wgSpecialPages['ContributionStatistics'] = 'SpecialContributionStatistics'; |
— | — | @@ -53,8 +52,8 @@ |
54 | 53 | $wgSpecialPages['ContributionTrackingStatistics'] = 'SpecialContributionTrackingStatistics'; |
55 | 54 | $wgSpecialPages['DailyTotal'] = 'SpecialDailyTotal'; |
56 | 55 | $wgSpecialPages['YearlyTotal'] = 'SpecialYearlyTotal'; |
57 | | -*/ |
58 | 56 | |
| 57 | +/* |
59 | 58 | // Temporarily redirect all pages to DisabledNotice |
60 | 59 | $wgSpecialPages['DisabledNotice'] = 'DisabledNotice'; |
61 | 60 | $wgSpecialPages['ContributionHistory'] = 'DisabledNotice'; |
— | — | @@ -64,6 +63,7 @@ |
65 | 64 | $wgSpecialPages['ContributionTrackingStatistics'] = 'DisabledNotice'; |
66 | 65 | $wgSpecialPages['DailyTotal'] = 'DisabledNotice'; |
67 | 66 | $wgSpecialPages['YearlyTotal'] = 'DisabledNotice'; |
| 67 | +*/ |
68 | 68 | |
69 | 69 | $wgSpecialPageGroups['ContributionHistory'] = 'contribution'; |
70 | 70 | $wgSpecialPageGroups['ContributionTotal'] = 'contribution'; |
Index: trunk/extensions/ContributionReporting/FundraiserStatistics_body.php |
— | — | @@ -31,8 +31,6 @@ |
32 | 32 | } |
33 | 33 | } |
34 | 34 | |
35 | | - $this->timezone = $wgRequest->getText( 'timezone', '+0:00' ); |
36 | | - |
37 | 35 | /* Configuration (this isn't totally static data, some of it gets built on the fly) */ |
38 | 36 | |
39 | 37 | $charts = array( |
— | — | @@ -85,7 +83,8 @@ |
86 | 84 | |
87 | 85 | /* Display */ |
88 | 86 | |
89 | | - $wgOut->addWikiMsg('contribstats-header'); |
| 87 | + $wgOut->addWikiMsg( 'contribstats-header' ); // Header (typically empty) |
| 88 | + |
90 | 89 | // Chart maximums |
91 | 90 | foreach ( $egFundraiserStatisticsFundraisers as $fundraiser ) { |
92 | 91 | foreach ( $charts as $name => $chart ) { |
— | — | @@ -99,12 +98,25 @@ |
100 | 99 | foreach ( $charts as $name => $chart ) { |
101 | 100 | $charts[$name]['factor'] = 300 / $chart['max']; |
102 | 101 | } |
| 102 | + |
103 | 103 | // HTML-time! |
104 | | - $view = 0; |
105 | | - $htmlViews = ''; |
| 104 | + |
| 105 | + // Each bar on the graph is associated with an individual data table. The ID linking the |
| 106 | + // bar and the table is stored in $dataTableId. |
| 107 | + $dataTableId = 0; |
| 108 | + $dataTablesHtml = ''; // This will contain the HTML for all the data tables |
106 | 109 | foreach ( $egFundraiserStatisticsFundraisers as $fundraiserIndex => $fundraiser ) { |
| 110 | + |
| 111 | + // Get all the daily data for a particular fundraiser |
107 | 112 | $days = $this->query( 'dailyTotals', $fundraiser['start'], $fundraiser['end'] ); |
108 | | - $mostRecentFundraiser = $fundraiserIndex == count( $egFundraiserStatisticsFundraisers ) - 1; |
| 113 | + |
| 114 | + // See if this is the most recent fundraiser or not |
| 115 | + if ( $fundraiserIndex == count( $egFundraiserStatisticsFundraisers ) - 1 ) { |
| 116 | + $mostRecentFundraiser = true; |
| 117 | + } else { |
| 118 | + $mostRecentFundraiser = false; |
| 119 | + } |
| 120 | + |
109 | 121 | foreach ( $charts as $name => $chart ) { |
110 | 122 | $column = 0; |
111 | 123 | foreach( $days as $i => $day ) { |
— | — | @@ -131,7 +143,7 @@ |
132 | 144 | $attributes = array( |
133 | 145 | 'style' => $style, |
134 | 146 | 'class' => "fundraiserstats-bar fundraiserstats-bar-{$fundraiser['id']}", |
135 | | - 'rel' => "fundraiserstats-view-box-{$view}", |
| 147 | + 'rel' => "fundraiserstats-view-box-{$dataTableId}", |
136 | 148 | ); |
137 | 149 | if ( $mostRecentFundraiser && $i == count( $days ) -1 ) { |
138 | 150 | $attributes['class'] .= ' fundraiserstats-current'; |
— | — | @@ -139,28 +151,31 @@ |
140 | 152 | $charts[$name]['data'][$column] .= Xml::tags( |
141 | 153 | 'td', array( 'valign' => 'bottom' ), Xml::element( 'div', $attributes, '', false ) |
142 | 154 | ); |
143 | | - $htmlView = Xml::openElement( 'tr' ); |
| 155 | + |
| 156 | + // Construct the data table for this day |
| 157 | + $dataTable = Xml::openElement( 'tr' ); |
144 | 158 | $count = 0; |
145 | 159 | foreach ( $charts as $subchart ) { |
146 | | - $htmlView .= Xml::element( |
| 160 | + $dataTable .= Xml::element( |
147 | 161 | 'td', array( 'width' => '16%', 'nowrap' => 'nowrap' ), wfMsg( $subchart['label'] ) |
148 | 162 | ); |
149 | | - $htmlView .= Xml::element( |
| 163 | + $dataTable .= Xml::element( |
150 | 164 | 'td', |
151 | 165 | array( 'width' => '16%', 'nowrap' => 'nowrap', 'align' => 'right' ), |
152 | 166 | $wgLang->formatNum( number_format( $day[$subchart['index']], $subchart['precision'] ) ) |
153 | 167 | ); |
154 | 168 | if ( ++$count % 3 == 0 ) { |
155 | | - $htmlView .= Xml::closeElement( 'tr' ) . Xml::openElement( 'tr' ); |
| 169 | + $dataTable .= Xml::closeElement( 'tr' ) . Xml::openElement( 'tr' ); |
156 | 170 | } |
157 | 171 | } |
158 | | - $htmlView .= Xml::closeElement( 'tr' ); |
159 | | - $htmlViews .= Xml::tags( |
| 172 | + $dataTable .= Xml::closeElement( 'tr' ); |
| 173 | + |
| 174 | + $dataTablesHtml .= Xml::tags( |
160 | 175 | 'div', |
161 | 176 | array( |
162 | | - 'id' => 'fundraiserstats-view-box-' . $view, |
| 177 | + 'id' => 'fundraiserstats-view-box-' . $dataTableId, |
163 | 178 | 'class' => 'fundraiserstats-view-box', |
164 | | - 'style' => 'display: ' . ( $view == 0 ? 'block' : 'none' ) |
| 179 | + 'style' => 'display: ' . ( $dataTableId == 0 ? 'block' : 'none' ) |
165 | 180 | ), |
166 | 181 | Xml::tags( |
167 | 182 | 'table', |
— | — | @@ -171,7 +186,7 @@ |
172 | 187 | Xml::tags( |
173 | 188 | 'td', |
174 | 189 | array( 'colspan' => 6 ), |
175 | | - Xml::element( 'h3', array( 'style' => 'float:right;color:gray;' ), $day[0] ) . |
| 190 | + Xml::element( 'h3', array( 'style' => 'float:right;color:gray;' ), $day[0] ) . // The date |
176 | 191 | Xml::tags( |
177 | 192 | 'h3', |
178 | 193 | array( 'style' => 'float:left;color:black;' ), |
— | — | @@ -180,11 +195,11 @@ |
181 | 196 | Xml::element( 'div', array( 'style' => 'clear:both;' ), '', false ) |
182 | 197 | ) |
183 | 198 | ) . |
184 | | - $htmlView |
| 199 | + $dataTable |
185 | 200 | ) |
186 | 201 | ); |
187 | 202 | $column++; |
188 | | - $view++; |
| 203 | + $dataTableId++; |
189 | 204 | } |
190 | 205 | } |
191 | 206 | } |
— | — | @@ -203,9 +218,6 @@ |
204 | 219 | } |
205 | 220 | $wgOut->addHTML( Xml::openElement( 'div', array( 'id' => 'configholder' ) ) ); |
206 | 221 | $wgOut->addHTML( $years ); |
207 | | - // TODO: Fix timezone feature to work with caching correctly. |
208 | | - // $wgOut->addHTML( wfMsg( 'fundraiserstats-time-zone' ).'<br/>' ); |
209 | | - // $wgOut->addHTML( ' '.Xml::listDropDown( 'timezone', $this->dropDownList( range ( -12, 14, 1 ) ), '', $this->timezone, '', 1 ).' '.wfMsg( 'fundraiserstats-utc' ) ); |
210 | 222 | $wgOut->addHTML( Xml::closeElement( 'div' ) ); |
211 | 223 | |
212 | 224 | $wgOut->addHTML( Xml::closeElement( 'form' ) ); |
— | — | @@ -213,11 +225,13 @@ |
214 | 226 | // Instructions |
215 | 227 | $wgOut->addWikiMsg( 'fundraiserstats-instructions' ); |
216 | 228 | |
| 229 | + $chartsHtml = ''; // This will contain the HTML for all of the bar charts and tabs |
| 230 | + |
217 | 231 | // Tabs |
| 232 | + $chartsHtml .= Xml::openElement( 'div', array( 'class' => 'fundraiserstats-chart-tabs' ) ); |
218 | 233 | $first = true; |
219 | | - $htmlCharts = Xml::openElement( 'div', array( 'class' => 'fundraiserstats-chart-tabs' ) ); |
220 | 234 | foreach ( $charts as $chart => $columns ) { |
221 | | - $htmlCharts .= Xml::tags( |
| 235 | + $chartsHtml .= Xml::tags( |
222 | 236 | 'div', |
223 | 237 | array( |
224 | 238 | 'id' => "fundraiserstats-chart-{$chart}-tab", |
— | — | @@ -228,11 +242,12 @@ |
229 | 243 | ); |
230 | 244 | $first = false; |
231 | 245 | } |
232 | | - $htmlCharts .= Xml::closeElement( 'div' ); |
| 246 | + $chartsHtml .= Xml::closeElement( 'div' ); |
| 247 | + |
233 | 248 | // Charts |
234 | 249 | $first = true; |
235 | 250 | foreach ( $charts as $name => $chart ) { |
236 | | - $htmlCharts .= Xml::tags( |
| 251 | + $chartsHtml .= Xml::tags( |
237 | 252 | 'div', |
238 | 253 | array( |
239 | 254 | 'id' => "fundraiserstats-chart-{$name}", |
— | — | @@ -256,23 +271,35 @@ |
257 | 272 | 'cellspacing' => 0, |
258 | 273 | 'border' => 0 |
259 | 274 | ), |
260 | | - Xml::tags( 'tr', null, Xml::tags( 'td', null, $htmlCharts ) ) . |
261 | | - Xml::tags( 'tr', null, Xml::tags( 'td', null, $htmlViews ) ) |
| 275 | + Xml::tags( 'tr', null, Xml::tags( 'td', null, $chartsHtml ) ) . |
| 276 | + Xml::tags( 'tr', null, Xml::tags( 'td', null, $dataTablesHtml ) ) |
262 | 277 | ) |
263 | 278 | ); |
264 | | - $wgOut->addWikiMsg('contribstats-footer'); |
| 279 | + $wgOut->addWikiMsg( 'contribstats-footer' ); // Footer (typically empty) |
265 | 280 | } |
266 | 281 | |
267 | 282 | /* Private Functions */ |
268 | 283 | |
| 284 | + /** |
| 285 | + * Retrieve the donation data from the database |
| 286 | + * |
| 287 | + * @param string $type Which type of query to do |
| 288 | + * @param string $start The start date for a fundraiser |
| 289 | + * @param string $end The end date for a fundraiser |
| 290 | + * @return an array of results or null |
| 291 | + */ |
269 | 292 | private function query( $type, $start, $end ) { |
270 | 293 | global $wgMemc, $egFundraiserStatisticsMinimum, $egFundraiserStatisticsMaximum, $egFundraiserStatisticsCacheTimeout; |
271 | 294 | |
| 295 | + // Conctruct the key for memcached |
272 | 296 | $key = wfMemcKey( 'fundraiserstatistics', $type, $start, $end ); |
| 297 | + |
| 298 | + // If result exists in memcached, use that |
273 | 299 | $cache = $wgMemc->get( $key ); |
274 | 300 | if ( $cache != false && $cache != -1 ) { |
275 | 301 | return $cache; |
276 | 302 | } |
| 303 | + |
277 | 304 | // Use database |
278 | 305 | $dbr = efContributionReportingConnection(); |
279 | 306 | $conditions = array( |
— | — | @@ -285,7 +312,7 @@ |
286 | 313 | case 'dailyTotals': |
287 | 314 | $select = $dbr->select( 'public_reporting', |
288 | 315 | array( |
289 | | - "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')", |
| 316 | + "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')", |
290 | 317 | 'sum(converted_amount)', |
291 | 318 | 'count(*)', |
292 | 319 | 'avg(converted_amount)', |
— | — | @@ -295,13 +322,14 @@ |
296 | 323 | __METHOD__ . '-dailyTotals', |
297 | 324 | array( |
298 | 325 | 'ORDER BY' => 'received', |
299 | | - 'GROUP BY' => "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')" |
| 326 | + 'GROUP BY' => "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')" |
300 | 327 | ) |
301 | 328 | ); |
302 | 329 | $result = array(); |
303 | 330 | $ytd = 0; |
304 | 331 | while ( $row = $dbr->fetchRow( $select ) ) { |
305 | | - $row[] = $ytd += $row[1]; // YTD |
| 332 | + // Insert the year-to-date amount as a record in the row (existing $ytd + sum) |
| 333 | + $row[5] = $ytd += $row[1]; |
306 | 334 | $result[] = $row; |
307 | 335 | } |
308 | 336 | break; |
— | — | @@ -312,7 +340,7 @@ |
313 | 341 | __METHOD__ . '-dailyTotalMax', |
314 | 342 | array( |
315 | 343 | 'ORDER BY' => 'sum DESC', |
316 | | - 'GROUP BY' => "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')" |
| 344 | + 'GROUP BY' => "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')" |
317 | 345 | ) |
318 | 346 | ); |
319 | 347 | break; |
— | — | @@ -330,7 +358,7 @@ |
331 | 359 | __METHOD__ . '-contributionsMax', |
332 | 360 | array( |
333 | 361 | 'ORDER BY' => 'sum DESC', |
334 | | - 'GROUP BY' => "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')" |
| 362 | + 'GROUP BY' => "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')" |
335 | 363 | ) |
336 | 364 | ); |
337 | 365 | break; |
— | — | @@ -341,7 +369,7 @@ |
342 | 370 | __METHOD__ . '-averagesMax', |
343 | 371 | array( |
344 | 372 | 'ORDER BY' => 'sum DESC', |
345 | | - 'GROUP BY' => "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')" |
| 373 | + 'GROUP BY' => "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')" |
346 | 374 | ) |
347 | 375 | ); |
348 | 376 | break; |
— | — | @@ -352,28 +380,16 @@ |
353 | 381 | __METHOD__ . '-maximumsMax', |
354 | 382 | array( |
355 | 383 | 'ORDER BY' => 'sum DESC', |
356 | | - 'GROUP BY' => "DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(received),'+00:00','$this->timezone'),'%Y-%m-%d')" |
| 384 | + 'GROUP BY' => "DATE_FORMAT(FROM_UNIXTIME(received),'%Y-%m-%d')" |
357 | 385 | ) |
358 | 386 | ); |
359 | 387 | break; |
360 | 388 | } |
361 | 389 | if ( isset( $result ) ) { |
| 390 | + // Store the result in memcached |
362 | 391 | $wgMemc->set( $key, $result, $egFundraiserStatisticsCacheTimeout ); |
363 | 392 | return $result; |
364 | 393 | } |
365 | 394 | return null; |
366 | 395 | } |
367 | | - |
368 | | - /** |
369 | | - * @param $values |
370 | | - * @return string |
371 | | - */ |
372 | | - private function dropDownList ( $values ) { |
373 | | - $dropDown = ''; |
374 | | - foreach ( $values as $value ) { |
375 | | - if ( $value >= 0 ) $dropDown .= '+'; |
376 | | - $dropDown .= "$value:00\n"; |
377 | | - } |
378 | | - return $dropDown; |
379 | | - } |
380 | 396 | } |