r96592 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r96591‎ | r96592 | r96593 >
Date:18:31, 8 September 2011
Author:demon
Status:ok
Tags:
Comment:
Followup to comments on r59048: remove everything related to Special:ClickTracking, since its unused
Modified paths:
  • /trunk/extensions/ClickTracking/ApiSpecialClickTracking.php (deleted) (history)
  • /trunk/extensions/ClickTracking/ClickTracking.alias.php (deleted) (history)
  • /trunk/extensions/ClickTracking/ClickTracking.i18n.php (modified) (history)
  • /trunk/extensions/ClickTracking/ClickTracking.php (modified) (history)
  • /trunk/extensions/ClickTracking/SpecialClickTracking.php (deleted) (history)
  • /trunk/extensions/ClickTracking/modules/ext.clickTracking.special.css (deleted) (history)
  • /trunk/extensions/ClickTracking/modules/ext.clickTracking.special.js (deleted) (history)

Diff [purge]

Index: trunk/extensions/ClickTracking/ClickTracking.alias.php
@@ -1,114 +0,0 @@
2 -<?php
3 -/**
4 - * Special page aliases for Usability Initiative ClickTracking extension
5 - *
6 - * @file
7 - * @ingroup Extensions
8 - */
9 -
10 -$specialPageAliases = array();
11 -
12 -/** English (English) */
13 -$specialPageAliases['en'] = array(
14 - 'ClickTracking' => array( 'ClickTracking' ),
15 -);
16 -
17 -/** Arabic (العربية) */
18 -$specialPageAliases['ar'] = array(
19 - 'ClickTracking' => array( 'تتبع_الضغط' ),
20 -);
21 -
22 -/** Egyptian Spoken Arabic (مصرى) */
23 -$specialPageAliases['arz'] = array(
24 - 'ClickTracking' => array( 'متابعة_الدوسات' ),
25 -);
26 -
27 -/** Breton (Brezhoneg) */
28 -$specialPageAliases['br'] = array(
29 - 'ClickTracking' => array( 'HeuliañKlikoù' ),
30 -);
31 -
32 -/** Esperanto (Esperanto) */
33 -$specialPageAliases['eo'] = array(
34 - 'ClickTracking' => array( 'Klakkaptilo' ),
35 -);
36 -
37 -/** Persian (فارسی) */
38 -$specialPageAliases['fa'] = array(
39 - 'ClickTracking' => array( 'تعقیب_کلیک' ),
40 -);
41 -
42 -/** 湘语 (湘语) */
43 -$specialPageAliases['hsn'] = array(
44 - 'ClickTracking' => array( '点击跟踪' ),
45 -);
46 -
47 -/** Haitian (Kreyòl ayisyen) */
48 -$specialPageAliases['ht'] = array(
49 - 'ClickTracking' => array( 'SwivKlik' ),
50 -);
51 -
52 -/** Interlingua (Interlingua) */
53 -$specialPageAliases['ia'] = array(
54 - 'ClickTracking' => array( 'Traciamento_de_clic' ),
55 -);
56 -
57 -/** Indonesian (Bahasa Indonesia) */
58 -$specialPageAliases['id'] = array(
59 - 'ClickTracking' => array( 'Pelacakan_klik', 'PelacakanKlik' ),
60 -);
61 -
62 -/** Italian (Italiano) */
63 -$specialPageAliases['it'] = array(
64 - 'ClickTracking' => array( 'TracciaClic' ),
65 -);
66 -
67 -/** Japanese (日本語) */
68 -$specialPageAliases['ja'] = array(
69 - 'ClickTracking' => array( 'クリック追跡' ),
70 -);
71 -
72 -/** Luxembourgish (Lëtzebuergesch) */
73 -$specialPageAliases['lb'] = array(
74 - 'ClickTracking' => array( 'Opzeechne_vun_de_Klicken' ),
75 -);
76 -
77 -/** Macedonian (Македонски) */
78 -$specialPageAliases['mk'] = array(
79 - 'ClickTracking' => array( 'СледењеНаСтискања' ),
80 -);
81 -
82 -/** Malayalam (മലയാളം) */
83 -$specialPageAliases['ml'] = array(
84 - 'ClickTracking' => array( 'ഞെക്കൽപിന്തുടരൽ' ),
85 -);
86 -
87 -/** Marathi (मराठी) */
88 -$specialPageAliases['mr'] = array(
89 - 'ClickTracking' => array( 'मागोवाटिचकवा' ),
90 -);
91 -
92 -/** Dutch (Nederlands) */
93 -$specialPageAliases['nl'] = array(
94 - 'ClickTracking' => array( 'Klikvolgen' ),
95 -);
96 -
97 -/** Norwegian (bokmål)‬ (‪Norsk (bokmål)‬) */
98 -$specialPageAliases['no'] = array(
99 - 'ClickTracking' => array( 'Klikksporing' ),
100 -);
101 -
102 -/** Turkish (Türkçe) */
103 -$specialPageAliases['tr'] = array(
104 - 'ClickTracking' => array( 'TıklamaTakibi' ),
105 -);
106 -
107 -/** Simplified Chinese (‪中文(简体)‬) */
108 -$specialPageAliases['zh-hans'] = array(
109 - 'ClickTracking' => array( '点击追踪' ),
110 -);
111 -
112 -/**
113 - * For backwards compatibility with MediaWiki 1.15 and earlier.
114 - */
115 -$aliases =& $specialPageAliases;
\ No newline at end of file
Index: trunk/extensions/ClickTracking/ApiSpecialClickTracking.php
@@ -1,138 +0,0 @@
2 -<?php
3 -/**
4 - * Click Tracking special page API extension
5 - *
6 - * @file
7 - * @ingroup API
8 - */
9 -
10 -class ApiSpecialClickTracking extends ApiBase {
11 -
12 - /**
13 - * API specialclicktracking action
14 - *
15 - * Parameters:
16 - * startdate: beginning of results
17 - * enddate: ending of results
18 - * eventid: identifier of event being queried
19 - * increment: how many days to increment
20 - *
21 - * @see includes/api/ApiBase#execute()
22 - */
23 - public function execute() {
24 - $params = $this->extractRequestParams();
25 - $this->validateParams( $params );
26 - $eventId = $params['eventid'];
27 - $startDate = $params['startdate'];
28 - $endDate = $params['enddate'];
29 - $increment = $params['increment'];
30 - $userDefString = $params['userdefs'];
31 -
32 - // This is if it's asking for tableData
33 - if ( isset( $params['tabledata'] ) ) {
34 - $tableData = SpecialClickTracking::buildRowArray( $startDate, $endDate, $userDefString );
35 - $this->getResult()->addValue( array( 'tablevals' ), 'vals', $tableData );
36 - } else {
37 - // Chart data
38 - try {
39 - $click_data = SpecialClickTracking::getChartData( $eventId, $startDate, $endDate, $increment, $userDefString );
40 - $this->getResult()->addValue( array( 'datapoints' ), 'expert', $click_data['expert'] );
41 - $this->getResult()->addValue( array( 'datapoints' ), 'basic', $click_data['basic'] );
42 - $this->getResult()->addValue( array( 'datapoints' ), 'intermediate', $click_data['intermediate'] );
43 - } catch ( Exception $e ) {
44 - /* No result */
45 - }
46 - }
47 - }
48 -
49 - /**
50 - * Required parameter check
51 - *
52 - * @param $params array params extracted from the POST
53 - */
54 - protected function validateParams( $params ) {
55 - // Check if event id parses to an int greater than zero
56 - if ( (int) $params['eventid'] < 0 ) {
57 - $this->dieUsage( 'Invalid event ID', 'badeventid' );
58 - }
59 -
60 - // Check start and end date are of proper format
61 - if ( $params['startdate'] != 0 && strptime( SpecialClickTracking::spaceOutDate( $params['startdate'] ), "%Y %m %d" ) === false ) {
62 - $this->dieUsage( "startdate not in YYYYMMDD format: <<{$params['startdate']}>>", 'badstartdate' );
63 - }
64 - if ( $params['enddate'] != 0 && strptime( SpecialClickTracking::spaceOutDate( $params['enddate'] ), "%Y %m %d" ) === false ) {
65 - $this->dieUsage( "enddate not in YYYYMMDD format: <<{$params['enddate']}>>", 'badenddate' );
66 - }
67 -
68 - // Check if increment is a positive integer
69 - if ( $params['increment'] <= 0 ) {
70 - $this->dieUsage( 'Invalid increment', 'badincrement' );
71 - }
72 -
73 - if ( json_decode( $params['userdefs'] ) == null ) {
74 - $this->dieUsage( "Invalid JSON encoding <<{$params['userdefs']}>>", 'badjson' );
75 - }
76 - }
77 -
78 - public function getParamDescription() {
79 - return array(
80 - 'eventid' => 'event ID (number)',
81 - 'startdate' => 'start date for data in YYYYMMDD format',
82 - 'enddate' => 'end date for the data in YYYYMMDD format',
83 - 'increment' => 'increment interval (in days) for data points',
84 - 'userdefs' => 'JSON object to encode user definitions',
85 - 'tabledata' => 'set to 1 for table data instead of chart data'
86 - );
87 - }
88 -
89 - public function getDescription() {
90 - return array(
91 - 'Returns data to the Special:ClickTracking visualization page'
92 - );
93 - }
94 -
95 - public function getPossibleErrors() {
96 - return array_merge( parent::getPossibleErrors(), array(
97 - array( 'code' => 'badeventid', 'info' => 'Invalid event ID' ),
98 - array( 'code' => 'badstartdate', 'info' => 'startdate not in YYYYMMDD format: <<\'startdate\'>>' ),
99 - array( 'code' => 'badenddate', 'info' => 'enddate not in YYYYMMDD format: <<\'enddate\'>>' ),
100 - array( 'code' => 'badincrement', 'info' => 'Invalid increment' ),
101 - array( 'code' => 'badjson', 'info' => 'Invalid JSON encoding <<\'userdefs\'>>' ),
102 - ) );
103 - }
104 -
105 - public function getAllowedParams() {
106 - return array(
107 - 'eventid' => array(
108 - ApiBase::PARAM_TYPE => 'integer',
109 - ApiBase::PARAM_MIN => 1,
110 - ApiBase::PARAM_REQUIRED => true,
111 - ),
112 - 'startdate' => array(
113 - ApiBase::PARAM_TYPE => 'integer',
114 - ApiBase::PARAM_REQUIRED => true,
115 - ),
116 - 'enddate' => array(
117 - ApiBase::PARAM_TYPE => 'integer',
118 - ApiBase::PARAM_REQUIRED => true,
119 - ),
120 - 'increment' => array(
121 - ApiBase::PARAM_TYPE => 'integer',
122 - ApiBase::PARAM_MIN => 1,
123 - ApiBase::PARAM_MAX => 365, // 1 year
124 - ApiBase::PARAM_REQUIRED => true,
125 - ),
126 - 'userdefs' => array(
127 - ApiBase::PARAM_TYPE => 'string',
128 - ApiBase::PARAM_REQUIRED => true,
129 - ),
130 - 'tabledata' => array(
131 - ApiBase::PARAM_TYPE => 'integer'
132 - ),
133 - );
134 - }
135 -
136 - public function getVersion() {
137 - return __CLASS__ . ': $Id$';
138 - }
139 -}
\ No newline at end of file
Index: trunk/extensions/ClickTracking/SpecialClickTracking.php
@@ -1,738 +0,0 @@
2 -<?php
3 -/**
4 - * Special:ClickTracking
5 - *
6 - * @file
7 - * @ingroup Extensions
8 - */
9 -
10 -class SpecialClickTracking extends SpecialPage {
11 -
12 - private static $minimum_date = '20091009'; // YYYYMMDD (+1 for today)
13 -
14 - private $user_defs = array();
15 -
16 - /**
17 - * Constructor -- set up the new special page
18 - */
19 - public function __construct() {
20 - parent::__construct( 'ClickTracking', 'clicktrack' );
21 - }
22 -
23 - function setDefaults() {
24 - $this->user_defs['basic'] = array(
25 - 'anonymous' => '1',
26 - 'total_contribs' => array( array( 'operation' => '<=', 'value' => '10' ) ),
27 - );
28 - $this->user_defs['intermediate'] = array(
29 - 'anonymous' => '0',
30 - 'total_contribs' => array(
31 - array( 'operation' => '<', 'value' => '400' ),
32 - array( 'operation' => '>', 'value' => '10' ),
33 - ),
34 - );
35 - $this->user_defs['expert'] = array(
36 - 'anonymous' => '0',
37 - 'total_contribs' => array( array( 'operation' => '>=', 'value' => '400' ) ),
38 - );
39 - }
40 -
41 - /**
42 - * Show the special page
43 - *
44 - * @param $par Mixed: parameter passed to the special page or null
45 - */
46 - public function execute( $par ) {
47 - global $wgOut, $wgUser;
48 -
49 - $wgOut->addModules( 'ext.clickTracking.special' );
50 -
51 - // Check permissions
52 - if ( !$this->userCanExecute( $wgUser ) ) {
53 - $this->displayRestrictionError();
54 - return;
55 - }
56 -
57 - $this->setHeaders();
58 - $this->setDefaults();
59 - $wgOut->addInlineScript( 'var wgClickTrackUserDefs = ' . json_encode( $this->user_defs ) );
60 - $wgOut->setPageTitle( wfMsg( 'ct-title' ) );
61 -
62 - $outputTable = '';
63 -
64 - // Grab top N
65 - $events = $this->getTopEvents();
66 -
67 - // Open table
68 - $outputTable .= Xml::openElement( 'table', array( 'class' => 'sortable click-data', 'id' => 'clicktrack_data_table' ) );
69 -
70 - // Create a row for every event
71 - $i = 0;
72 - $db_result;
73 -
74 - // Build row headers
75 - $header_row = array();
76 -
77 - $header_row['event_header'] = wfMsg( 'ct-event-name' );
78 - $header_row['expert_header'] = wfMsg( 'ct-expert-header' );
79 - $header_row['intermediate_header'] = wfMsg( 'ct-intermediate-header' );
80 - $header_row['basic_header'] = wfMsg( 'ct-beginner-header' );
81 - $header_row['total_header'] = wfMsg( 'ct-total-header' );
82 - $outputTable .= Xml::buildTableRow( array( 'class' => 'table_headers' ), $header_row );
83 -
84 - // Build event rows
85 - while ( ( $db_result = $events->fetchRow() ) != null ) {
86 - ++$i;
87 - $outputTable .= $this->buildRow( $db_result, $i, $this->user_defs );
88 - }
89 -
90 - // Close table
91 - $outputTable .= Xml::closeElement( 'table' );
92 -
93 - $wgOut->addHTML( $outputTable );
94 -
95 - $wgOut->addHTML( $this->buildDateRange() );
96 -
97 - // Build chart
98 - $wgOut->addHTML( $this->buildChart( 'advanced.hide', 10, '20090815', '20090902', 1 ) );
99 - $wgOut->addHTML( $this->buildChartDialog() );
100 - $wgOut->addHTML( $this->buildUserDefBlankDialog() );
101 - }
102 -
103 - /**
104 - * Gets the data to build a chart for PHP or JS purposes
105 - *
106 - * @param $event_id Integer: event ID this chart is for
107 - * @param $minTime Integer: minimum day
108 - * @param $maxTime Integer: maximum day
109 - * @param $increment Integer: number of day(s) to increment in units
110 - * @param $userDefs Array: user defintions
111 - * @param $isUserDefsJSON Boolean: true if userDefs is JSON
112 - * @return array with chart info
113 - */
114 - static function getChartData( $event_id, $minTime, $maxTime, $increment, $userDefs, $isUserDefsJSON = true ) {
115 - // Get data
116 - date_default_timezone_set( 'UTC' );
117 -
118 - if ( $maxTime == 0 ) {
119 - $maxTime = gmdate( 'Ymd', time() ); // today
120 - }
121 - if ( $minTime == 0 ) {
122 - $minTime = self::$minimum_date;
123 - }
124 -
125 - // FIXME: On PHP 5.3+, this will be MUCH cleaner
126 - $currBeginDate = new DateTime( $minTime );
127 - $currEndDate = new DateTime( $minTime );
128 - $endDate = new DateTime( $maxTime );
129 -
130 - // Get user definitions
131 - if ( $isUserDefsJSON ) {
132 - $userDefs = json_decode( $userDefs, true );
133 - }
134 -
135 - $basicUserData = array();
136 - $intermediateUserData = array();
137 - $expertUserData = array();
138 -
139 - // PHP 5.3...hurry!
140 - $plural = ( $increment == 1 ? '' : 's' );
141 -
142 - while ( $currEndDate->format( 'U' ) < $endDate->format( 'U' ) ) {
143 - $currEndDate->modify( "+$increment day$plural" );
144 -
145 - $minDate = $currBeginDate->format( 'Ymd' );
146 - $maxDate = $currEndDate->format( 'Ymd' );
147 -
148 - $basicUserData[] = self::getTableValue( $event_id, $userDefs['basic'], $minDate, $maxDate );
149 - $intermediateUserData[] = self::getTableValue( $event_id, $userDefs['intermediate'], $minDate, $maxDate );
150 - $expertUserData[] = self::getTableValue( $event_id, $userDefs['expert'], $minDate, $maxDate );
151 - $currBeginDate->modify( "+$increment day$plural" );
152 - }
153 - return array(
154 - 'expert' => $expertUserData,
155 - 'basic' => $basicUserData,
156 - 'intermediate' => $intermediateUserData
157 - );
158 - }
159 -
160 - function buildChart( $event_name, $event_id, $minTime, $maxTime, $increment ) {
161 - $chartData = self::getChartData(
162 - $event_id, $minTime, $maxTime,
163 - $increment, $this->user_defs, false
164 - );
165 - $chartSrc = $this->getGoogleChartParams(
166 - $event_id,
167 - $event_name,
168 - $minTime,
169 - $maxTime,
170 - $chartData['basic'],
171 - $chartData['intermediate'],
172 - $chartData['expert']
173 - );
174 - return Xml::element( 'img', array( 'src' => $chartSrc, 'id' => 'chart_img' ) );
175 - }
176 -
177 - function getGoogleChartParams(
178 - $event_id, $event_name, $minDate, $maxDate, $basicUserData, $intermediateUserData, $expertUserData
179 - ) {
180 - $max = max( max( $basicUserData ), max( $intermediateUserData ), max( $expertUserData ) );
181 - return 'http://chart.apis.google.com/chart?' . wfArrayToCGI(
182 - array(
183 - 'chs' => '400x400',
184 - 'cht' => 'lc',
185 - 'chco' => 'FF0000,0000FF,00FF00',
186 - 'chtt' => "$event_name from $minDate to $maxDate",
187 - 'chdl' => 'Expert|Intermediate|Beginner',
188 - 'chxt' => 'x,y',
189 - 'chd' => 't:' . implode( ',', $expertUserData ) . '|' .
190 - implode( ',', $intermediateUserData ) . '|' . implode( ',', $basicUserData ),
191 - 'chds' => "0,$max,0,$max,0,$max"
192 - ) );
193 - }
194 -
195 - function buildUserDefBlankDialog() {
196 - $control = '';
197 - $control .= Xml::openElement( 'div', array( 'id' => 'user_def_dialog', 'class' => 'dialog' ) );
198 -
199 - // currently editing...----|
200 - $control .= Xml::openElement( 'form', array( 'id' => 'user_definition_form', 'class' => 'user_def_form' ) );
201 - $control .= Xml::openElement( 'fieldset', array( 'id' => 'user_def_alter_fieldset' ) );
202 - $control .= Xml::openElement( 'legend', array( 'id' => 'user_def_alter_legend' ) );
203 - $control .= wfMsg( 'ct-editing' );
204 - $control .= Xml::closeElement( 'legend' );
205 -
206 - // [] anonymous users?
207 - $control .= Xml::openElement( 'div', array( 'id' => 'anon_users_div', 'class' => 'checkbox_div control_div' ) );
208 - $control .= Xml::openElement(
209 - 'input', array( 'type' => 'checkbox', 'id' => 'anon_users_checkbox', 'class' => 'user_def_checkbox' )
210 - );
211 - $control .= Xml::closeElement( 'input' );
212 - $control .= wfMsg( 'ct-anon-users' );
213 - $control .= Xml::closeElement( 'div' );
214 -
215 - // ----------------
216 - $control .= Xml::openElement( 'hr' );
217 - $control .= Xml::closeElement( 'hr' );
218 - $control .= Xml::openElement( 'div', array( 'id' => 'contrib_opts_container' ) );
219 -
220 - // [] users with contributions [>=V] [n ]
221 - $control .= Xml::openElement(
222 - 'div', array( 'id' => 'total_users_contrib_div', 'class' => 'checkbox_div control_div' )
223 - );
224 - $control .= Xml::openElement(
225 - 'input', array( 'type' => 'checkbox', 'id' => 'contrib_checkbox', 'class' => 'user_def_checkbox' )
226 - );
227 - $control .= Xml::closeElement( 'input' );
228 - $control .= wfMsg( 'ct-user-contribs' );
229 -
230 -
231 - $control .= Xml::closeElement( 'div' );
232 -
233 - // [] contributions in timespan 1
234 - $control .= Xml::openElement(
235 - 'div', array( 'id' => 'contrib_span_1_div', 'class' => 'checkbox_div control_div' )
236 - );
237 -
238 - $control .= Xml::openElement( 'div', array( 'id' => 'contrib_span_1_text_div', 'class' => 'checkbox_div' ) );
239 - $control .= Xml::openElement(
240 - 'input', array( 'type' => 'checkbox', 'id' => 'contrib_span_1_checkbox', 'class' => 'user_def_checkbox' )
241 - );
242 - $control .= Xml::closeElement( 'input' );
243 - $control .= wfMsg( 'ct-user-span' ) . ' 1';
244 - $control .= Xml::closeElement( 'div' );
245 - $control .= Xml::closeElement( 'div' );
246 -
247 - // [] contributions in timespan 2
248 - $control .= Xml::openElement(
249 - 'div', array( 'id' => 'contrib_span_2_div', 'class' => 'checkbox_div control_div' )
250 - );
251 -
252 - $control .= Xml::openElement( 'div', array( 'id' => 'contrib_span_2_text_div', 'class' => 'checkbox_div' ) );
253 - $control .= Xml::openElement(
254 - 'input', array( 'type' => 'checkbox', 'id' => 'contrib_span_2_checkbox', 'class' => 'user_def_checkbox' )
255 - );
256 - $control .= Xml::closeElement( 'input' );
257 - $control .= wfMsg( 'ct-user-span' ) . ' 2';
258 - $control .= Xml::closeElement( 'div' );
259 - $control .= Xml::closeElement( 'div' );
260 -
261 - // [] contributions in timespan 3
262 - $control .= Xml::openElement(
263 - 'div', array( 'id' => 'contrib_span_3_div', 'class' => 'checkbox_div control_div' )
264 - );
265 -
266 - $control .= Xml::openElement( 'div', array( 'id' => 'contrib_span_3_text_div', 'class' => 'checkbox_div' ) );
267 - $control .= Xml::openElement(
268 - 'input', array( 'type' => 'checkbox', 'id' => 'contrib_span_3_checkbox', 'class' => 'user_def_checkbox' )
269 - );
270 - $control .= Xml::closeElement( 'input' );
271 - $control .= wfMsg( 'ct-user-span' ) . ' 3';
272 - $control .= Xml::closeElement( 'div' );
273 - $control .= Xml::closeElement( 'div' );
274 -
275 - $control .= Xml::closeElement( 'div' );// close contrib opts
276 -
277 - $control .= Xml::closeElement( 'fieldset' );
278 - $control .= Xml::closeElement( 'form' );
279 - $control .= Xml::closeElement( 'div' );
280 - return $control;
281 - }
282 -
283 - function buildUserDefNumberSelect( $include_checkbox, $include_and, $ids ) {
284 - $control = '';
285 - if ( $include_checkbox ) {
286 - $control .= Xml::openElement(
287 - 'input', array( 'type' => 'checkbox', 'id' => "{$ids}_checkbox", 'class' => 'number_select_checkbox' )
288 - );
289 - $control .= Xml::closeElement( 'input' );
290 - }
291 -
292 - if ( $include_and ) {
293 - $control .= wfMsg( 'ct-and' );
294 - }
295 -
296 - $control .= Xml::openElement( 'select', array( 'id' => "{$ids}_ltgt", 'class' => 'number_select_ltgt' ) );
297 - $control .= Xml::openElement(
298 - 'option', array( 'id' => '{$ids}_lt', 'class' => 'number_select_ltgt_opt', 'value' => 'lt' )
299 - );
300 - $control .= '&lt;=';
301 - $control .= Xml::closeElement( 'option' );
302 - $control .= Xml::openElement(
303 - 'option', array( 'id' => '{$ids}_gt', 'class' => 'number_select_ltgt_opt', 'value' => 'gt' )
304 - );
305 - $control .= '&gt;=';
306 - $control .= Xml::closeElement( 'option' );
307 - $control .= Xml::closeElement( 'select' );
308 - $control .= Xml::openElement(
309 - 'input', array( 'type' => 'text', 'id' => "{$ids}_text", 'class' => 'number_select_text' )
310 - );
311 - $control .= Xml::closeElement( 'input' );
312 - return $control;
313 - }
314 -
315 - function buildChartDialog() {
316 - $control = '';
317 - $control .= Xml::openElement( 'div', array( 'id' => 'chart_dialog', 'class' => 'dialog' ) );
318 -
319 - $control .= Xml::openElement( 'form', array( 'id' => 'chart_dialog_form', 'class' => 'chart_form' ) );
320 - $control .= Xml::openElement( 'fieldset', array( 'id' => 'chart_dialog_alter_fieldset' ) );
321 - $control .= Xml::openElement( 'legend', array( 'id' => 'chart_dialog_alter_legend' ) );
322 - $control .= wfMsg( 'ct-increment-by' );
323 - $control .= Xml::closeElement( 'legend' );
324 -
325 - $control .= Xml::openElement( 'table', array( 'id' => 'chart_dialog_increment_table' ) );
326 - $control .= Xml::openElement( 'tbody', array( 'id' => 'chart_dialog_increment_tbody' ) );
327 -
328 - $control .= Xml::openElement( 'tr', array( 'id' => 'chart_dialog_increment_row' ) );
329 -
330 - $control .= Xml::openElement( 'td', array( 'id' => 'chart_dialog_increment_cell' ) );
331 - $control .= Xml::openElement(
332 - 'input',
333 - array( 'type' => 'text', 'id' => 'chart_increment', 'class' => 'chart_dialog_area', 'value' => '1' )
334 - );
335 - $control .= Xml::closeElement( 'input' );
336 - $control .= Xml::closeElement( 'td' );
337 -
338 - $control .= Xml::openElement( 'td', array( 'id' => 'chart_dialog_button_cell' ) );
339 - $control .= Xml::openElement(
340 - 'input', array( 'type' => 'button', 'id' => 'change_graph', 'value' => wfMsg( 'ct-change-graph' ) )
341 - );
342 - $control .= Xml::closeElement( 'input' );
343 - $control .= Xml::closeElement( 'td' );
344 -
345 - $control .= Xml::closeElement( 'tr' );
346 -
347 - $control .= Xml::closeElement( 'tbody' );
348 - $control .= Xml::closeElement( 'table' );
349 - $control .= Xml::closeElement( 'fieldset' );
350 - $control .= Xml::closeElement( 'form' );
351 - $control .= Xml::closeElement( 'div' );
352 - return $control;
353 - }
354 -
355 - function buildDateRange() {
356 - $control = Xml::openElement( 'form', array( 'id' => 'date_range' ) );
357 -
358 - $control .= Xml::openElement( 'fieldset', array( 'id' => 'date_range_fieldset' ) );
359 - $control .= Xml::openElement( 'legend', array( 'id' => 'date_range_legend' ) );
360 - $control .= wfMsg( 'ct-date-range' );
361 - $control .= Xml::closeElement( 'legend' );
362 -
363 - $control .= Xml::openElement( 'table', array( 'id' => 'date_range_table' ) );
364 - $control .= Xml::openElement( 'tbody', array( 'id' => 'date_range_tbody' ) );
365 -
366 - $control .= Xml::openElement( 'tr', array( 'id' => 'start_date_row' ) );
367 -
368 - $control .= Xml::openElement( 'td', array( 'id' => 'start_date_label', 'class' => 'date_range_label' ) );
369 - $control .= Xml::openElement(
370 - 'input',
371 - array(
372 - 'type' => 'checkbox', 'id' => 'start_date_checkbox', 'class' => 'date_range_checkbox', 'checked' => ''
373 - )
374 - );
375 - $control .= Xml::closeElement( 'input' );
376 - $control .= wfMsg( 'ct-start-date' );
377 - $control .= Xml::closeElement( 'td' );
378 -
379 - $control .= Xml::openElement( 'td', array( 'id' => 'start_date_textarea' ) );
380 - $control .= Xml::openElement(
381 - 'input', array( 'type' => 'text', 'id' => 'start_date', 'class' => 'date_range_input' )
382 - );
383 - $control .= Xml::closeElement( 'input' );
384 - $control .= Xml::closeElement( 'td' );
385 -
386 - $control .= Xml::closeElement( 'tr' );
387 -
388 - $control .= Xml::openElement( 'tr', array( 'id' => 'end_date_row' ) );
389 -
390 - $control .= Xml::openElement( 'td', array( 'id' => 'end_date_label', 'class' => 'date_range_label' ) );
391 - $control .= Xml::openElement(
392 - 'input',
393 - array(
394 - 'type' => 'checkbox', 'id' => 'end_date_checkbox', 'class' => 'date_range_checkbox', 'checked' => ''
395 - )
396 - );
397 - $control .= Xml::closeElement( 'input' );
398 - $control .= wfMsg( 'ct-end-date' );
399 - $control .= Xml::closeElement( 'td' );
400 -
401 - $control .= Xml::openElement( 'td', array( 'id' => 'end_date_textarea' ) );
402 - $control .= Xml::openElement(
403 - 'input', array( 'type' => 'text', 'id' => 'end_date', 'class' => 'date_range_input' )
404 - );
405 - $control .= Xml::closeElement( 'input' );
406 - $control .= Xml::closeElement( 'td' );
407 -
408 - $control .= Xml::closeElement( 'tr' );
409 -
410 - $control .= Xml::openElement( 'tr', array( 'id' => 'update_row' ) );
411 -
412 - $control .= Xml::openElement( 'td' );
413 - $control .= Xml::closeElement( 'td' );
414 -
415 - $control .= Xml::openElement( 'td', array( 'id' => 'update_table_button_td' ) );
416 - $control .= Xml::openElement(
417 - 'input',
418 - array(
419 - 'type' => 'button',
420 - 'id' => 'update_table_button',
421 - 'class' => 'update_button',
422 - 'value' => wfMsg( 'ct-update-table' )
423 - )
424 - );
425 - $control .= Xml::closeElement( 'input' );
426 - $control .= Xml::closeElement( 'td' );
427 -
428 - $control .= Xml::closeElement( 'tr' );
429 -
430 - $control .= Xml::closeElement( 'tbody' );
431 - $control .= Xml::closeElement( 'table' );
432 - $control .= Xml::closeElement( 'fieldset' );
433 -
434 - $control .= Xml::closeElement( 'form' );
435 -
436 - return $control;
437 - }
438 -
439 - /**
440 - *
441 - * @param $minTime
442 - * @param $maxTime
443 - * @param $userDefs
444 - * @param $is_JSON
445 - * @return Array
446 - */
447 - public static function buildRowArray( $minTime, $maxTime, $userDefs, $is_JSON = true ) {
448 - if ( $minTime == 0 ) {
449 - $minTime = self::$minimum_date;
450 - }
451 - if ( $maxTime == 0 ) {
452 - $maxTime = gmdate( 'Ymd', time() ); // today
453 - }
454 -
455 - if ( $is_JSON ) {
456 - $userDefs = json_decode( $userDefs, true );
457 - }
458 -
459 - $events = self::getTopEvents( $minTime, $maxTime );
460 -
461 - $returnArray = array();
462 -
463 - while ( ( $data_result = $events->fetchRow() ) != null ) {
464 - $outputArray = array();
465 - $outputArray['event_name'] = $data_result['event_name'];
466 - $outputArray['event_id'] = $data_result['event_id'];
467 - $outputArray['expert'] = self::getTableValue( $data_result['event_id'], $userDefs['expert'] );
468 - $outputArray['intermediate'] = self::getTableValue( $data_result['event_id'], $userDefs['intermediate'] );
469 - $outputArray['basic'] = self::getTableValue( $data_result['event_id'], $userDefs['basic'] );
470 - $outputArray['total'] = $data_result['totalevtid'];
471 - $returnArray[] = $outputArray;
472 - }
473 -
474 - return $returnArray;
475 - }
476 -
477 - function buildRow( $data_result, $row_count, $userDefs ) {
478 - $outputRow = Xml::openElement( 'tr', array( 'class' => 'table_data_row' ) );
479 -
480 - // event name
481 - $outputRow .= Xml::openElement( 'td',
482 - array( 'class' => 'event_name', 'id' => "event_name_$row_count", 'value' => $data_result['event_id'] ) );
483 - $outputRow .= $data_result['event_name'];
484 - $outputRow .= Xml::closeElement( 'td' );
485 -
486 - // advanced users
487 - $cellValue = self::getTableValue( $data_result['event_id'], $userDefs['expert'] );
488 - $outputRow .= Xml::openElement( 'td',
489 - array(
490 - 'class' => 'event_data expert_data',
491 - 'id' => "event_expert_$row_count",
492 - 'value' => $cellValue
493 - )
494 - );
495 - $outputRow .= $cellValue;
496 - $outputRow .= Xml::closeElement( 'td' );
497 -
498 - // intermediate users
499 - $cellValue = self::getTableValue( $data_result['event_id'], $userDefs['intermediate'] );
500 - $outputRow .= Xml::openElement( 'td',
501 - array(
502 - 'class' => 'event_data intermediate_data',
503 - 'id' => "event_intermediate_$row_count",
504 - 'value' => $cellValue
505 - )
506 - );
507 - $outputRow .= $cellValue;
508 - $outputRow .= Xml::closeElement( 'td' );
509 -
510 - // basic users
511 - $cellValue = self::getTableValue( $data_result['event_id'], $userDefs['basic'] );
512 - $outputRow .= Xml::openElement( 'td',
513 - array(
514 - 'class' => 'event_data basic_data',
515 - 'id' => "event_basic_$row_count",
516 - 'value' => $cellValue
517 - )
518 - );
519 - $outputRow .= $cellValue;
520 - $outputRow .= Xml::closeElement( 'td' );
521 -
522 - // totals
523 - $cellValue = $data_result['totalevtid'];
524 - $outputRow .= Xml::openElement( 'td',
525 - array(
526 - 'class' => 'event_data total_data',
527 - 'id' => "total_$row_count",
528 - 'value' => $cellValue
529 - )
530 - );
531 - $outputRow .= $cellValue;
532 - $outputRow .= Xml::closeElement( 'td' );
533 -
534 - $outputRow .= Xml::closeElement( 'tr' );
535 -
536 - return $outputRow;
537 - }
538 -
539 - /**
540 - * Space out the dates for date validation
541 - *
542 - * @param $dateWithoutSpaces Integer: date without spaces
543 - * @return date with spaces
544 - */
545 - public static function spaceOutDate( $dateWithoutSpaces ) {
546 - return (
547 - substr( $dateWithoutSpaces, 0, 4 ) . ' ' .
548 - substr( $dateWithoutSpaces, 4, 2 ) . ' ' .
549 - substr( $dateWithoutSpaces, 6, 2 )
550 - );
551 - }
552 -
553 - /**
554 - * Get time constraints
555 - *
556 - * @param $minTime Integer: minimum day (YYYYMMDD)
557 - * @param $maxTime Integer: max day (YYYYMMDD)
558 - * @return Array
559 - * NOTE: once some of the constraints have been finalized, this will use more of the Database functions and not raw
560 - * SQL
561 - */
562 - static function getTimeConstraints( $minTime, $maxTime ) {
563 - if (
564 - $minTime == 0 || $maxTime == 0 ||
565 - ( strptime( SpecialClickTracking::spaceOutDate( $minTime ), "%Y %m %d" ) === false ) ||
566 - ( strptime( SpecialClickTracking::spaceOutDate( $minTime ), "%Y %m %d" ) === false )
567 - )
568 - {
569 - return array();
570 - } else {
571 - // the dates are stored in the DB as MW_TIMESTAMP formats, add the zeroes to fix that
572 - $minTime .= '000000';
573 - $maxTime .= '000000';
574 -
575 - $dbr = wfGetDB( DB_SLAVE );
576 -
577 - // time constraint array
578 - return array(
579 - "`action_time` >= " . $dbr->addQuotes( $minTime ),
580 - "`action_time` <= " . $dbr->addQuotes( $maxTime )
581 - );
582 - }
583 - }
584 -
585 - /**
586 - * Gets the top N events as set in the page pref
587 - *
588 - * @param $time_constraint_statement
589 - * @return unknown_type
590 - * NOTE: once some of the constraints have been finalized, this will use more of the Database functions and not raw
591 - * SQL
592 - */
593 - public static function getTopEvents( $minTime = '', $maxTime = '', $normalize_top_results = false ) {
594 - $timeConstraintStatement = self::getTimeConstraints( $minTime, $maxTime );
595 - $timeConstraint = $timeConstraintStatement;
596 -
597 - $dbr = wfGetDB( DB_SLAVE );
598 -
599 - // NOTE: This query is a performance nightmare
600 - // Permission to run it is restricted by default
601 - $dbResult = $dbr->select(
602 - array( 'click_tracking', 'click_tracking_events' ),
603 - array( 'COUNT(event_id) AS totalevtid', 'event_id', 'event_name' ),
604 - $timeConstraint,
605 - __METHOD__,
606 - array( 'GROUP BY' => 'event_id', 'ORDER BY' => 'totalevtid DESC' ),
607 - array( 'click_tracking_events' =>
608 - array( 'LEFT JOIN', 'event_id=id' )
609 - )
610 - );
611 -
612 - /*
613 - $sql = "select count(event_id) as totalevtid, event_id,event_name from click_tracking" .
614 - " LEFT JOIN click_tracking_events ON event_id=click_tracking_events.id".
615 - " $time_constraint group by event_id order by totalevtid desc";
616 - */
617 -
618 - // returns count(event_id),event_id, event_name, top one first
619 - return $dbResult;
620 - }
621 -
622 - /**
623 - * Gets a table value for a given User ID
624 - * NOTE: once some of the constraints have been finalized, this will use more of the Database functions and not raw
625 - * SQL
626 - */
627 - static function getTableValue( $event_id, $userDef, $minTime = '', $maxTime = '', $normalize_results = false ) {
628 - $dbr = wfGetDB( DB_SLAVE );
629 - $conds = array_merge(
630 - self::getTimeConstraints( $minTime, $maxTime ),
631 - SpecialClickTracking::buildUserDefConstraints( $userDef ),
632 - array( 'event_id' => $event_id )
633 - );
634 - return wfGetDB( DB_SLAVE )->selectField(
635 - 'click_tracking',
636 - 'COUNT(*)',
637 - $conds,
638 - __METHOD__
639 - );
640 - }
641 -
642 - /**
643 - * Generates a query for a user type definition
644 - *
645 - * @param $def Array
646 - * @return Array: array containing the built SQL query
647 - */
648 - public static function buildUserDefConstraints( $def ) {
649 - $dbr = wfGetDB( DB_SLAVE );
650 -
651 - $include_anon_users = ( empty( $def['anonymous'] ) ? array() : $def['anonymous'] );
652 - $total_contribs = ( empty( $def['total_contribs'] ) ? array() : $def['total_contribs'] );
653 - $contrib_1 = ( empty( $def['contrib_1'] ) ? array() : $def['contrib_1'] );
654 - $contrib_2 = ( empty( $def['contrib_2'] ) ? array() : $def['contrib_2'] );
655 - $contrib_3 = ( empty( $def['contrib_3'] ) ? array() : $def['contrib_3'] );
656 -
657 - $or_conds = array();
658 - $and_conds = array();
659 - $sql = '';
660 -
661 - if ( (boolean)$include_anon_users ) {
662 - $or_conds[] = array(
663 - 'field' => 'is_logged_in',
664 - 'operation' => '=',
665 - 'value' => '0'
666 - );
667 - }
668 -
669 - if ( !empty( $total_contribs ) ) {
670 - foreach ( $total_contribs as $contribs ) {
671 - $and_conds[] = array(
672 - 'field' => 'user_total_contribs',
673 - 'operation' => SpecialClickTracking::validateOperation( $contribs['operation'] ),
674 - 'value' => intval( $contribs['value'] )
675 - );
676 - }
677 - }
678 -
679 - if ( !empty( $contrib_1 ) ) {
680 - foreach ( $contrib_1 as $contribs ) {
681 - $and_conds[] = array(
682 - 'field' => 'user_contribs_span1',
683 - 'operation' => SpecialClickTracking::validateOperation( $contribs['operation'] ),
684 - 'value' => intval( $contribs['value'] )
685 - );
686 - }
687 - }
688 -
689 - if ( !empty( $contrib_2 ) ) {
690 - foreach ( $contrib_2 as $contribs ) {
691 - $and_conds[] = array(
692 - 'field' => 'user_contribs_span2',
693 - 'operation' => SpecialClickTracking::validateOperation( $contribs['operation'] ),
694 - 'value' => intval( $contribs['value'] )
695 - );
696 - }
697 - }
698 -
699 - if ( !empty( $contrib_3 ) ) {
700 - foreach ( $contrib_3 as $contribs ) {
701 - $and_conds[] = array(
702 - 'field' => 'user_contribs_span3',
703 - 'operation' => SpecialClickTracking::validateOperation( $contribs['operation'] ),
704 - 'value' => intval( $contribs['value'] )
705 - );
706 - }
707 - }
708 -
709 - foreach ( $and_conds as $cond ) {
710 - if ( !empty( $sql ) ) {
711 - $sql .= ' AND ';
712 - }
713 - $sql .= $cond['field'] . ' ' . $cond['operation'] . ' ' . $dbr->addQuotes( $cond['value'] );
714 - }
715 -
716 - foreach ( $or_conds as $cond ) {
717 - if ( !empty( $sql ) ) {
718 - $sql .= ' OR ';
719 - }
720 - $sql .= $cond['field'] . ' ' . $cond['operation'] . ' ' . $dbr->addQuotes( $cond['value'] );
721 - }
722 -
723 - return array( $sql );
724 - }
725 -
726 - public static function validateOperation( $operation ) {
727 - $o_trim = trim( $operation );
728 - switch( $o_trim ) { // valid operations
729 - case '>':
730 - case '<':
731 - case '<=':
732 - case '>=':
733 - case '=':
734 - return $o_trim;
735 - default:
736 - return '=';
737 - }
738 - }
739 -}
\ No newline at end of file
Index: trunk/extensions/ClickTracking/modules/ext.clickTracking.special.css
@@ -1,65 +0,0 @@
2 -/*
3 - * CSS for ClickTracking extension special page
4 - */
5 -
6 -.table_headers {
7 - font-weight: bold;
8 - border: bottom;
9 -}
10 -
11 -.table_data_row {
12 - text-align: center;
13 -}
14 -
15 -.table_data_row .event_name {
16 - text-align: left;
17 - font-weight: bold;
18 -}
19 -
20 -#clicktrack_data_table {
21 - float: left;
22 -}
23 -
24 -#chart_img {
25 - float: left;
26 - margin-left: 90px;
27 -}
28 -
29 -#change_graph_cell {
30 - text-align: right;
31 -}
32 -
33 -.disabled_option {
34 - color: #999999;
35 -}
36 -
37 -.hidden {
38 - display: none;
39 -}
40 -
41 -.control_div {
42 - margin: 10px;
43 - clear: both;
44 -}
45 -
46 -.sub_option_div {
47 - margin-top: 4px;
48 - margin-left: 15px;
49 -}
50 -
51 -.sub_option_div input[type="text"] {
52 - width: 20px;
53 - margin-left: 10px;
54 -}
55 -
56 -#date_range {
57 - display: inline;
58 - float: left;
59 - width: 200px;
60 -}
61 -
62 -.add_condition_button {
63 - float: right;
64 - color: blue;
65 - cursor: pointer;
66 -}
\ No newline at end of file
Index: trunk/extensions/ClickTracking/modules/ext.clickTracking.special.js
@@ -1,514 +0,0 @@
2 -/*
3 - * JavaScript for ClickTracking extension special page
4 - */
5 -
6 -( function( $ ) {
7 -
8 - $.getUserDefsFromDialog = function() {
9 - var currUserDefs = [];
10 - if ( $( '#anon_users_checkbox' ).is( ':checked' ) ) {
11 - currUserDefs.anonymous = 1;
12 - } else {
13 - currUserDefs.anonymous = 0;
14 - }
15 -
16 - var getCheckBoxData = function( contribName ) {
17 - if ( $( '#' + contribName + '_checkbox' ).is( ':checked' ) ) {
18 - currUserDefs[contribName] = [];
19 - } else {
20 - return;
21 - }
22 - var totalConds = $( '#' + contribName + '_div' ).data( 'totalConditions' );
23 - var i;
24 -
25 - for ( i = 1; i <= totalConds; i++ ) {
26 - if ( $( '#' + contribName + '_' + i + '_checkbox' ).is( ':checked' ) ) {
27 - $( '#' + contribName + '_' + i + '_ltgt' ).children().each( function() {
28 - if ( $( this ).is( ':selected' ) ) {
29 - var currentCond = [];
30 - switch ( $( this ).attr( "value" ) ) {
31 - case 'lt':
32 - currentCond.operation = '<';
33 - break;
34 - case 'lteq':
35 - currentCond.operation = '<=';
36 - break;
37 - case 'gt':
38 - currentCond.operation = '>';
39 - break;
40 - case 'gteq':
41 - currentCond.operation = '>=';
42 - break;
43 - default:
44 - currentCond.operation = '<';
45 - break;
46 - }
47 - currentCond.value = $( '#' + contribName + '_' + i + '_text' ).val();
48 - currUserDefs[contribName].push( currentCond );
49 - }
50 - } );
51 - } // ifchecked
52 - } // forloop
53 - };
54 -
55 - getCheckBoxData( 'total_contribs' );
56 - getCheckBoxData( 'contribs_span_1' );
57 - getCheckBoxData( 'contribs_span_2' );
58 - getCheckBoxData( 'contribs_span_3' );
59 - wgClickTrackUserDefs[$( '#user_def_alter_legend' ).data( 'currentlyEditing' )] = currUserDefs;
60 - };
61 -
62 - $.renderUserDefDialogWith = function( userDef, defName ) {
63 - // change name
64 - $( '#user_def_alter_legend' ).text( $( '#user_def_alter_legend' ).data( 'defaultChangeText' ) + ' ' + defName );
65 - $( '#user_def_alter_legend' ).data( 'currentlyEditing', defName );
66 -
67 - var setContribs = function( conditionArray, contribName ) {
68 - initialDiv = $( '<div></div>' ).attr( 'id', contribName + '_div' );
69 - initialDiv.addClass( 'checkbox_div' );
70 - initialDiv.addClass( 'control_div' );
71 -
72 - textDiv = $( '<div></div>' ).attr( 'id', contribName + '_text_div' );
73 - mainCheckbox = $( '<input>' ).attr( 'id', contribName + '_checkbox' );
74 - mainCheckbox.attr( 'type', 'checkbox' );
75 - mainCheckbox.addClass( 'user_def_checkbox' );
76 -
77 - if ( conditionArray.length > 0 ) {
78 - mainCheckbox.attr( 'checked', true );
79 - }
80 -
81 - textDiv.append( mainCheckbox );
82 - textDiv.text( contribName ); // i18n txt here
83 - textDiv.css( 'display', 'inline' );
84 - initialDiv.append( mainCheckbox );
85 - initialDiv.append( textDiv );
86 -
87 - var buildConditionDiv = function( condition, counter, isChecked ) {
88 - conditionDiv = $( '<div></div>' ).attr( 'id', contribName + '_range_' + counter + '_div' );
89 - conditionDiv.addClass( 'checkbox_div' );
90 - conditionDiv.addClass( 'sub_option_div' );
91 -
92 - // initialDiv.append(conditionDiv);
93 - cCheckbox = $( '<input type="checkbox"></input>' ).attr( 'id',
94 - contribName + '_' + counter + '_checkbox' );
95 - // cCheckbox.attr('type', 'checkbox');
96 - if ( isChecked ) {
97 - cCheckbox.attr( 'checked', true );
98 - }
99 -
100 - cCheckbox.addClass( 'number_select_checkbox' );
101 - conditionDiv.append( cCheckbox );
102 -
103 - cSelect = $( '<select></select>' ).attr( 'id', contribName + '_' + counter + '_ltgt' );
104 - cSelect.addClass( 'number_select_ltgt' );
105 -
106 - cOpt1 = $( '<option></option>' ).attr( 'id', contribName + '_' + counter + '_lt' );
107 - cOpt1.addClass( 'number_select_ltgt_opt' );
108 - cOpt1.attr( 'value', 'lt' );
109 - cOpt1.text( '<' );
110 - if ( condition.operation == '<' ) {
111 - cOpt1.attr( 'selected', true );
112 - }
113 -
114 - cOpt2 = $( '<option></option>' ).attr( 'id', contribName + '_' + counter + '_gt' );
115 - cOpt2.addClass( 'number_select_ltgt_opt' );
116 - cOpt2.attr( 'value', 'gt' );
117 - cOpt2.text( '>' );
118 - if ( condition.operation == '>' ) {
119 - cOpt2.attr( 'selected', true );
120 - }
121 -
122 - cOpt3 = $( '<option></option>' ).attr( 'id', contribName + '_' + counter + '_lteq' );
123 - cOpt3.addClass( 'number_select_ltgt_opt' );
124 - cOpt3.attr( 'value', 'lteq' );
125 - cOpt3.text( '<=' );
126 - if ( condition.operation == '<=' ) {
127 - cOpt3.attr( 'selected', true );
128 - }
129 -
130 - cOpt4 = $( '<option></option>' ).attr( 'id', contribName + '_' + counter + '_gteq' );
131 - cOpt4.addClass( 'number_select_ltgt_opt' );
132 - cOpt4.attr( 'value', 'gteq' );
133 - cOpt4.text( '>=' );
134 - if ( condition.operation == '>=' ) {
135 - cOpt4.attr( 'selected', true );
136 - }
137 -
138 - cSelect.append( cOpt1 );
139 - cSelect.append( cOpt2 );
140 - cSelect.append( cOpt3 );
141 - cSelect.append( cOpt4 );
142 - conditionDiv.append( cSelect );
143 -
144 - cTextInput = $( '<input></input>' ).attr( 'id', contribName + '_' + counter + '_text' );
145 - cTextInput.addClass( 'number_select_text' );
146 - cTextInput.attr( 'value', condition.value );
147 - conditionDiv.append( cTextInput );
148 -
149 - return conditionDiv;
150 - };
151 -
152 - var i = 0;
153 - for ( var condition in conditionArray ) {
154 - i++;
155 - var conditionDiv = buildConditionDiv( conditionArray[condition], i, true );
156 - initialDiv.append( conditionDiv );
157 - } // forloop
158 -
159 - initialDiv.data( 'totalConditions', i );
160 - addConditions = $( '<div></div>' ).attr( 'id', contribName + '_addbutton' );
161 - addConditions.data( 'contribName', contribName );
162 - addConditions.addClass( 'add_condition_button' );
163 - addConditions.text( '+' );
164 - initialDiv.append( addConditions );
165 - addConditions.click( function() {
166 - var initDiv = $( '#' + $( this ).data( 'contribName' ) + '_div' );
167 - var totalConds = initDiv.data( 'totalConditions' );
168 - totalConds++;
169 - initDiv.data( 'totalConditions', totalConds );
170 - var tmpCond = [];
171 - tmpCond.operation = ' ';
172 - tmpCond.value = ' ';
173 -
174 - buildConditionDiv( tmpCond, totalConds ).insertBefore( $( this ) );
175 - initDiv.data( 'totalConditions', totalConds, false );
176 - } );
177 -
178 - return initialDiv;
179 - }; // setcontribs
180 -
181 - // check anonymous
182 - var anon = false;
183 - if ( parseInt( userDef.anonymous ) == 1 ) {
184 - anon = true;
185 - }
186 - $( '#anon_users_checkbox' ).attr( 'checked', anon );
187 -
188 - // clear out old contents
189 - $( '#contrib_opts_container' ).empty();
190 -
191 - var setup_set_contribs = function( contribName ) {
192 - var current_contribs = userDef[contribName];
193 - if ( current_contribs == undefined ) {
194 - current_contribs = [];
195 - }
196 - $( '#contrib_opts_container' ).append( setContribs( current_contribs, contribName ) );
197 - };
198 -
199 - // total contribs
200 - setup_set_contribs( 'total_contribs' );
201 - setup_set_contribs( 'contribs_span_1' );
202 - setup_set_contribs( 'contribs_span_2' );
203 - setup_set_contribs( 'contribs_span_3' );
204 -
205 - // OK button
206 - var okButton = $( '<input>' ).attr( 'id', 'ok_button' );
207 - okButton.attr( 'type', 'button' );
208 - okButton.attr( 'value', 'ok' );
209 - okButton.click( function() {
210 - $.getUserDefsFromDialog();
211 - $( '#user_def_dialog' ).dialog( 'close' );
212 - } );
213 - $( '#contrib_opts_container' ).append( okButton );
214 - }; // renderUserDefDialogWith
215 -
216 - // functions
217 - $.updateChart = function() {
218 - event_name = $( '#chart_img' ).data( 'event_name' );
219 -
220 - var processChartJSON = function( data, status ) {
221 -
222 - var getMax = function( findMax ) {
223 - var retval = Number.MIN_VALUE;
224 - for ( var i in findMax ) {
225 - if ( findMax[i] > retval ) {
226 - retval = findMax[i];
227 - }
228 - }
229 - return retval;
230 - };
231 -
232 - max1 = getMax( data.datapoints.expert );
233 - max2 = getMax( data.datapoints.intermediate );
234 - max3 = getMax( data.datapoints.basic );
235 - max = Math.max( max3, Math.max( max1, max2 ) );
236 - chartURL = 'http://chart.apis.google.com/chart?' + 'chs=400x400&' + 'cht=lc&'
237 - + 'chco=FF0000,0000FF,00FF00&' + 'chtt=' + event_name + ' from ' + $( '#start_date' ).val()
238 - + ' to ' + $( '#end_date' ).val() + '&' + 'chdl=' + 'Expert|Intermediate|Beginner' + '&'
239 - + 'chxt=x,y&' + 'chd=t:' + data.datapoints.expert.join( ',' ) + '|'
240 - + data.datapoints.intermediate.join( ',' ) + '|' + data.datapoints.basic.join( ',' )
241 - + '&' + 'chds=0,' + max + ',0,' + max + ',0,' + max;
242 - $( '#chart_img' ).attr( 'src', chartURL );
243 - };
244 -
245 - start_date = $( '#start_date' ).val();
246 - if ( $( '#start_date' ).hasClass( 'hidden' ) ) {
247 - start_date = '0';
248 - }
249 -
250 - end_date = $( '#end_date' ).val();
251 - if ( $( '#end_date' ).hasClass( 'hidden' ) ) {
252 - end_date = '0';
253 - }
254 -
255 - // post relevant info
256 - $.post( wgScriptPath + '/api.php', {
257 - 'action' : 'specialclicktracking',
258 - 'format' : 'json',
259 - 'eventid' : $( '#chart_img' ).data( 'eventid' ),
260 - 'increment' : $( '#chart_increment' ).val(),
261 - 'startdate' : start_date,
262 - 'enddate' : end_date,
263 - 'userdefs' : $.toJSON( wgClickTrackUserDefs )
264 - }, processChartJSON, 'json' );
265 - };
266 -
267 - // pretty colors for the table
268 - $.colorizeTable = function() {
269 - // expert
270 -
271 - // get totals
272 - var expert_total = 0;
273 -
274 - $( '.expert_data' ).each( function() {
275 - expert_total += parseInt( $( this ).attr( 'value' ) );
276 - } );
277 -
278 - // set proper red shade
279 - $( '.expert_data' ).each( function() {
280 - var rval = 255;
281 - var gval = ( expert_total == 0 ? 255 : 255 - ( 255 * $( this ).attr( 'value' ) / expert_total ) );
282 - var bval = gval;
283 - rgbString = 'rgb(' + parseInt( rval ) + ',' + parseInt( gval ) + ',' + parseInt( bval ) + ')';
284 - $( this ).data( 'rgb', rgbString );
285 - $( this ).css( 'color', rgbString );
286 - $( this ).css( 'background-color', rgbString );
287 - } );
288 -
289 - // intermediate
290 -
291 - // total
292 - var intermediate_total = 0;
293 - $( '.intermediate_data' ).each( function() {
294 - intermediate_total += parseInt( $( this ).attr( 'value' ) );
295 - } );
296 -
297 - // blue shade
298 - $( '.intermediate_data' ).each(
299 - function() {
300 - var rval = ( intermediate_total == 0 ? 255
301 - : 255 - ( 255 * $( this ).attr( 'value' ) / intermediate_total ) );
302 - var gval = rval;
303 - var bval = 255;
304 - rgbString = 'rgb(' + parseInt( rval ) + ',' + parseInt( gval ) + ',' + parseInt( bval ) + ')';
305 - $( this ).data( 'rgb', rgbString );
306 - $( this ).css( 'color', rgbString );
307 - $( this ).css( 'background-color', rgbString );
308 - } );
309 -
310 - // total
311 - var basic_total = 0;
312 - $( '.basic_data' ).each( function() {
313 - basic_total += parseInt( $( this ).attr( 'value' ) );
314 - } );
315 -
316 - // green shade
317 - $( '.basic_data' ).each( function() {
318 - var rval = ( basic_total == 0 ? 255 : 255 - ( 255 * $( this ).attr( 'value' ) / basic_total ) );
319 - var gval = 255;
320 - var bval = rval;
321 - rgbString = 'rgb(' + parseInt( rval ) + ',' + parseInt( gval ) + ',' + parseInt( bval ) + ')';
322 - $( this ).data( 'rgb', rgbString );
323 - $( this ).css( {
324 - 'color': rgbString,
325 - 'background-color': rgbString
326 - } );
327 - } );
328 -
329 - // I wanted to do this with classes, but the element's style rule wins over class rule
330 - // and each element has its own alternative color
331 - $( '.event_data' ).mouseover( function() {
332 - $( this ).css( {
333 - 'color': '#000000',
334 - 'background-color': '#FFFFFF'
335 - } );
336 - } );
337 -
338 - $( '.event_data' ).mouseout( function() {
339 - rgbString = $( this ).data( 'rgb' );
340 - $( this ).css( {
341 - 'color': rgbString,
342 - 'background-color': rgbString
343 - } );
344 - } );
345 -
346 - }; // colorize
347 -
348 - $.updateTable = function() {
349 - var processTableJSON = function( data, status ) {
350 - // clear
351 - $( '.table_data_row' ).remove();
352 -
353 - var row_count = 0;
354 - for ( var row_iter in data.tablevals.vals ) {
355 - var row = data.tablevals.vals[row_iter]; // really, JS?
356 - row_count++;
357 -
358 - var outputRow = $( '<tr></tr>' );
359 - outputRow.addClass( 'table_data_row' );
360 -
361 - var cell = $( '<td></td>' ).attr( 'id', 'event_name_' + row_count );
362 - cell
363 - .addClass( 'event_name' )
364 - .attr( 'value', row.event_id )
365 - .text( row.event_name );
366 - outputRow.append( cell );
367 -
368 - var createClassCell = function( userclass ) {
369 - var newcell = $( '<td></td>' ).attr( 'id', 'event_' + userclass + '_' + row_count );
370 - newcell.addClass( 'event_data' );
371 - newcell.addClass( userclass + '_data' );
372 - newcell.text( row[userclass] );
373 - newcell.attr( 'value', row[userclass] );
374 - outputRow.append( newcell );
375 - };
376 -
377 - createClassCell( 'expert' );
378 - createClassCell( 'intermediate' );
379 - createClassCell( 'basic' );
380 - createClassCell( 'total' );
381 - $( '#clicktrack_data_table' ).append( outputRow );
382 - }
383 -
384 - $.colorizeTable();
385 - $.changeDataLinks();
386 - };
387 -
388 - start_date = $( '#start_date' ).val();
389 - if ( $( '#start_date' ).hasClass( 'hidden' ) ) {
390 - start_date = '0';
391 - }
392 -
393 - end_date = $( '#end_date' ).val();
394 - if ( $( '#end_date' ).hasClass( 'hidden' ) ) {
395 - end_date = '0';
396 - }
397 -
398 - // post relevant info
399 - $.post( wgScriptPath + '/api.php', {
400 - 'action' : 'specialclicktracking',
401 - 'format' : 'json',
402 - 'eventid' : 1,
403 - 'increment' : $( '#chart_increment' ).val(),
404 - 'startdate' : start_date,
405 - 'enddate' : end_date,
406 - 'userdefs' : $.toJSON( wgClickTrackUserDefs ),
407 - 'tabledata' : 1
408 - }, processTableJSON, 'json' );
409 -
410 - }; // updateTable
411 -
412 - $.setUIControls = function() {
413 - // Set up date ranges
414 -
415 - // date-pickers for start and end dates
416 - $( '.date_range_input' ).each( function() {
417 - $( this ).datepicker();
418 - $( this ).datepicker( 'option', 'dateFormat', 'yymmdd' );
419 - } );
420 - var startDate = new Date();
421 - $( '#start_date' ).val( '20091009' ); // click_tracking start date as default
422 -
423 - var toggleDateInput = function( tableRow ) {
424 - var checked = false;
425 - tableRow.children().each( function() {
426 - if ( checked == false ) {
427 - checked = $( this ).children( 'input:checkbox' ).eq( 0 ).is( ':checked' );
428 - }
429 - } );
430 -
431 - if ( checked ) {
432 - tableRow.removeClass( 'disabled_option' );
433 - tableRow.children( 'td' ).each( function() {
434 - $( this ).children( '.date_range_input' ).removeClass( 'hidden' );
435 - } );
436 - } else {
437 - tableRow.children( 'td' ).each( function() {
438 - $( this ).children( '.date_range_input' ).addClass( 'hidden' );
439 - } );
440 - tableRow.addClass( 'disabled_option' );
441 - }
442 - };
443 -
444 - $( '.date_range_checkbox' ).click( function() {
445 - toggleDateInput( $( this ).closest( 'tr' ) );
446 - } );
447 -
448 - // update table
449 - $( '#update_table_button' ).click( $.updateTable );
450 -
451 - // Chart dialog
452 - $( '#chart_dialog' ).dialog( {
453 - autoOpen : false,
454 - width : 400
455 - } );
456 - $( '#chart_img' ).css( 'cursor', 'pointer' );
457 - $( '#chart_img' ).click( function() {
458 - $( '#chart_dialog' ).dialog( 'open' );
459 - } );
460 -
461 - $( '#chart_increment' ).data( 'value', $( '#chart_increment' ).val() );
462 -
463 - $( '#change_graph' ).click( function() {
464 - $( '#chart_dialog' ).dialog( 'close' );
465 -
466 - // check if the value actually changed, if so, update and increment things accordingly
467 - if ( $( '#chart_increment' ).data( 'value' ) != $( '#chart_increment' ).val() ) {
468 - $( '#chart_increment' ).data( 'value', $( '#chart_increment' ).val() );
469 - $.updateChart();
470 - }
471 -
472 - } );
473 -
474 - // Change user info dialog
475 - $( '#user_def_dialog' ).dialog( {
476 - autoOpen : false,
477 - width : 400
478 - } );
479 - $( '#user_def_alter_legend' ).data( 'defaultChangeText', $( '#user_def_alter_legend' ).text() );
480 -
481 - // Change user/intermediate/expert dialogs
482 - var loadHeaderInfo = function( headerName ) {
483 - $( '#' + headerName + '_header' )
484 - .css( 'cursor', 'pointer' )
485 - .click( function() {
486 - $.renderUserDefDialogWith( wgClickTrackUserDefs[headerName], headerName );
487 - $( '#user_def_dialog' ).dialog( 'open' );
488 - } );
489 - }; // headername
490 -
491 - loadHeaderInfo( 'basic' );
492 - loadHeaderInfo( 'intermediate' );
493 - loadHeaderInfo( 'expert' );
494 - };
495 -
496 - $.changeDataLinks = function() {
497 - $( '.event_name' )
498 - .css( 'cursor', 'pointer' )
499 - .click( function() {
500 - $( '#chart_img' ).data( 'eventid', $( this ).attr( 'value' ) );
501 - $( '#chart_img' ).data( 'event_name', $( this ).text() );
502 - $.updateChart();
503 - } ); // click
504 - }; // addlink
505 -
506 - // @FIXME: Where is this supposed to return to -- Krinkle 2011-04-27
507 - // - commented out for now.
508 - //return $( this );
509 -
510 -// colorize the table on document.ready
511 -$( $.colorizeTable );
512 -$( $.changeDataLinks );
513 -$( $.setUIControls );
514 -
515 -} )( jQuery );
Index: trunk/extensions/ClickTracking/ClickTracking.i18n.php
@@ -14,26 +14,6 @@
1515 $messages['en'] = array(
1616 'clicktracking' => 'Usability Initiative click tracking',
1717 'clicktracking-desc' => 'Click tracking for tracking events that do not cause a page refresh',
18 - 'ct-title' => 'Aggregated user clicks',
19 - 'ct-event-name' => 'Event name',
20 - 'ct-expert-header' => '"Expert" clicks',
21 - 'ct-intermediate-header' => '"Intermediate" clicks',
22 - 'ct-beginner-header' => '"Beginner" clicks',
23 - 'ct-total-header' => 'Total clicks',
24 - 'ct-start-date' => 'Start Date (YYYYMMDD)',
25 - 'ct-end-date' => 'End Date (YYYYMMDD)',
26 - 'ct-increment-by' =>'Number of days each data point represents',
27 - 'ct-change-graph' =>'Change graph',
28 - 'ct-beginner' => 'Beginner',
29 - 'ct-intermediate' => 'Intermediate',
30 - 'ct-expert' => 'Expert',
31 - 'ct-date-range' => 'Date range',
32 - 'ct-editing' => 'Currently editing:',
33 - 'ct-anon-users' => 'Anonymous users',
34 - 'ct-user-contribs' => 'Total user contributions',
35 - 'ct-user-span' => 'User contributions in timespan',
36 - 'ct-and' => 'and',
37 - 'ct-update-table' => 'Update table',
3818 );
3919
4020 /** Message documentation (Message documentation)
Index: trunk/extensions/ClickTracking/ClickTracking.php
@@ -46,8 +46,6 @@
4747 // Autoload classes
4848 $wgAutoloadClasses['ClickTrackingHooks'] = $dir . 'ClickTracking.hooks.php';
4949 $wgAutoloadClasses['ApiClickTracking'] = $dir . 'ApiClickTracking.php';
50 -$wgAutoloadClasses['SpecialClickTracking'] = $dir . 'SpecialClickTracking.php';
51 -$wgAutoloadClasses['ApiSpecialClickTracking'] = $dir . 'ApiSpecialClickTracking.php';
5250
5351 // Hooked functions
5452 $wgHooks['LoadExtensionSchemaUpdates'][] = 'ClickTrackingHooks::loadExtensionSchemaUpdates';
@@ -61,18 +59,9 @@
6260
6361 // API modules
6462 $wgAPIModules['clicktracking'] = 'ApiClickTracking';
65 -$wgAPIModules['specialclicktracking'] = 'ApiSpecialClickTracking';
6663
67 -// New special page
68 -$wgSpecialPages['ClickTracking'] = 'SpecialClickTracking';
69 -
70 -// New user right, required to use Special:ClickTracking
71 -$wgAvailableRights[] = 'clicktrack';
72 -$wgGroupPermissions['sysop']['clicktrack'] = true;
73 -
7464 // i18n
7565 $wgExtensionMessagesFiles['ClickTracking'] = $dir . 'ClickTracking.i18n.php';
76 -$wgExtensionAliasesFiles['ClickTracking'] = $dir . 'ClickTracking.alias.php';
7766
7867 // Resource modules
7968 $ctResourceTemplate = array(
@@ -87,11 +76,6 @@
8877 'scripts' => 'ext.clickTracking.js',
8978 'dependencies' => 'jquery.clickTracking',
9079 ) + $ctResourceTemplate;
91 -$wgResourceModules['ext.clickTracking.special'] = array(
92 - 'scripts' => 'ext.clickTracking.special.js',
93 - 'styles' => 'ext.clickTracking.special.css',
94 - 'dependencies' => array( 'jquery.json', 'jquery.ui.datepicker', 'jquery.ui.dialog' ),
95 -) + $ctResourceTemplate;
9680 $wgResourceModules['ext.UserBuckets'] = array(
9781 'scripts' => 'ext.UserBuckets.js',
9882 'dependencies' => array('jquery.clickTracking', 'jquery.json', 'jquery.cookie'),

Follow-up revisions

RevisionCommit summaryAuthorDate
r96597Remove alias file per r96592raymond19:05, 8 September 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r59048add trailing zeroes for MW_TIMESTAMP formatnimishg02:00, 14 November 2009

Status & tagging log