r101455 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101454‎ | r101455 | r101456 >
Date:07:55, 1 November 2011
Author:questpc
Status:deferred
Tags:
Comment:
Refactoring of XLS export. Fixed bug when adjascent proposal parts of question type text were not merged together when stored in dbtokens and then serialized.
Modified paths:
  • /trunk/extensions/QPoll/ctrl/question/qp_textquestion.php (modified) (history)
  • /trunk/extensions/QPoll/i18n/qp.i18n.php (modified) (history)
  • /trunk/extensions/QPoll/includes/qp_excel.php (deleted) (history)
  • /trunk/extensions/QPoll/includes/qp_xlswriter.php (added) (history)
  • /trunk/extensions/QPoll/qp_user.php (modified) (history)
  • /trunk/extensions/QPoll/specials/qp_results.php (modified) (history)
  • /trunk/extensions/QPoll/view/xls (added) (history)
  • /trunk/extensions/QPoll/view/xls/qp_xlspoll.php (added) (history)
  • /trunk/extensions/QPoll/view/xls/qp_xlstabularquestion.php (added) (history)
  • /trunk/extensions/QPoll/view/xls/qp_xlstextquestion.php (added) (history)

Diff [purge]

Index: trunk/extensions/QPoll/i18n/qp.i18n.php
@@ -238,7 +238,7 @@
239239 'qp_error_too_many_spans' => 'There cannot be more category groups defined than the total count of subcategories.',
240240 'qp_error_too_long_category_option_value' => 'Question type="text" categories with more than one text option to chose are displayed as html select/options list. Submitted (chosen) option value is stored in the database field. If the length of chosen value is too long, the value will be partially lost and select/option will not be properly highlighted. That\'s why the length limit is enforced.',
241241 'qp_error_too_long_category_options_values' => 'Question type="text" categories with more than one text option to chose are displayed as html select/options list. Submitted (chosen) options values are stored in the database field. If the total length of chosen values is too long, some of the values will be partially lost and select/options will not be properly highlighted. That\'s why the length limit is enforced.',
242 - 'qp_error_too_long_proposal_text' => "Question type=\"text\" stores it's proposal parts and category definitions in 'proposal_text' field of database table, serialized. If serialized data is longer than database table field length, some of data will be lost and unserialization will be impossible. That's why the length limit is enforced.",
 242+ 'qp_error_too_long_proposal_text' => "Question type=\"text\" stores it's proposal parts and category definitions in 'proposal_text' field of database table, serialized. If serialized data is longer than database table field length, some of data will be lost and unserialization will be impossible. Also, proposal name (which may be used by interpretation script) is stored in the same field, when defined. That's why the length limit is enforced.",
243243 'qp_error_too_few_spans' => 'Every category group should include at least two subcategories',
244244 'qp_error_no_interpretation' => 'Title of interpretation script was specified in poll header, but no article was found with that title. Either remove "interpretation" xml attribute of poll or create the title specified by "interpretation" attribute.',
245245 'qp_error_interpretation_no_return' => 'Interpretation script missed an return statement.',
Index: trunk/extensions/QPoll/specials/qp_results.php
@@ -274,38 +274,38 @@
275275 try {
276276 require_once( qp_Setup::$ExtDir . '/Excel/Excel_Writer.php' );
277277 $xls_fname = tempnam( "", ".xls" );
278 - $xls_workbook = new Spreadsheet_Excel_Writer_Workbook( $xls_fname );
279 - $xls_workbook->setVersion( 8 );
280 - $qp_xls = qp_Excel::newFromWorksheet( $xls_workbook->addworksheet() );
 278+ $qp_xls = new qp_XlsPoll( $xls_fname );
281279 # setup common formats
282 - $format = array(
283 - 'heading' => $xls_workbook->addformat( array( 'bold' => 1 ) ),
284 - 'answer' => $xls_workbook->addformat( array( 'fgcolor' => 0x1A, 'border' => 1 ) ),
285 - 'even' => $xls_workbook->addformat( array( 'fgcolor' => 0x2A, 'border' => 1 ) ),
286 - 'odd' => $xls_workbook->addformat( array( 'fgcolor' => 0x23, 'border' => 1 ) )
287 - );
288 - $format['answer']->setAlign( 'left' );
289 - $format['even']->setAlign( 'left' );
290 - $format['odd']->setAlign( 'left' );
 280+ $qp_xls->addFormats( array(
 281+ 'heading' => array( 'bold' => 1 ),
 282+ 'answer' => array( 'fgcolor' => 0x1A /* 26 */, 'border' => 1 ),
 283+ 'even' => array( 'fgcolor' => 0x2A /* 42 */, 'border' => 1 ),
 284+ 'odd' => array( 'fgcolor' => 0x23 /* 35 */, 'border' => 1 )
 285+ ) );
 286+ $qp_xls->getFormat( 'answer' )->setAlign( 'left' );
 287+ $qp_xls->getFormat( 'even' )->setAlign( 'left' );
 288+ $qp_xls->getFormat( 'odd' )->setAlign( 'left' );
291289 switch ( $cmd ) {
292290 case 'voices_xls' :
293 - $qp_xls->voicesToXLS( $format, $pollStore );
 291+ $qp_xls->voicesToXLS( $pollStore );
294292 break;
295293 case 'stats_xls' :
296294 # statistics export uses additional formats
297295 $percent_num_format = '[Blue]0.0%;[Red]-0.0%;[Black]0%';
298 - $format['percent'] = $xls_workbook->addformat( array( 'fgcolor' => 0x1A, 'border' => 1 ) );
299 - $format['percent']->setAlign( 'left' );
300 - $format['percent']->setNumFormat( $percent_num_format );
301 - $format['even']->setNumFormat( $percent_num_format );
302 - $format['odd']->setNumFormat( $percent_num_format );
303 - $qp_xls->statsToXLS( $format, $pollStore );
 296+ $qp_xls->addFormats( array(
 297+ 'percent' => array( 'fgcolor' => 0x1A, 'border' => 1 )
 298+ ) );
 299+ $qp_xls->getFormat( 'percent' )->setAlign( 'left' );
 300+ $qp_xls->getFormat( 'percent' )->setNumFormat( $percent_num_format );
 301+ $qp_xls->getFormat( 'even' )->setNumFormat( $percent_num_format );
 302+ $qp_xls->getFormat( 'odd' )->setNumFormat( $percent_num_format );
 303+ $qp_xls->statsToXLS( $pollStore );
304304 break;
305305 case 'interpretation_xls' :
306 - $qp_xls->interpretationToXLS( $format, $pollStore );
 306+ $qp_xls->interpretationToXLS( $pollStore );
307307 break;
308308 }
309 - $xls_workbook->close();
 309+ $qp_xls->closeWorkbook();
310310 header( 'Content-Type: application/x-msexcel; name="' . $poll_id . '.xls"' );
311311 header( 'Content-Disposition: inline; filename="' . $poll_id . '.xls"' );
312312 $fxls = @fopen( $xls_fname, "rb" );
Index: trunk/extensions/QPoll/ctrl/question/qp_textquestion.php
@@ -468,6 +468,7 @@
469469 # set proposal name (if any)
470470 $prop_name = qp_QuestionData::splitRawProposal( $raw );
471471 $this->dbtokens = $brace_stack = array();
 472+ $dbtokens_idx = -1;
472473 $catId = 0;
473474 $last_brace = '';
474475 $this->rawtokens = preg_split( $this->propCatPattern, $raw, -1, PREG_SPLIT_DELIM_CAPTURE );
@@ -508,7 +509,7 @@
509510 if ( array_key_exists( 'iscat', $brace_match ) ) {
510511 $matching_closed_brace = '';
511512 # add new category input options for the storage
512 - $this->dbtokens[] = $opt->input_options;
 513+ $this->dbtokens[++$dbtokens_idx] = $opt->input_options;
513514 # setup mCategories
514515 $this->mCategories[$catId] = array( 'name' => strval( $catId ) );
515516 # load proposal/category answer (when available)
@@ -524,7 +525,11 @@
525526 $opt->addToLastOption( $token );
526527 } else {
527528 # add new proposal part
528 - $this->dbtokens[] = strval( $token );
 529+ if ( $dbtokens_idx >= 0 && is_string( $this->dbtokens[$dbtokens_idx] ) ) {
 530+ $this->dbtokens[$dbtokens_idx] .= strval( $token );
 531+ } else {
 532+ $this->dbtokens[++$dbtokens_idx] = strval( $token );
 533+ }
529534 $this->propview->addProposalPart( $token );
530535 }
531536 }
Index: trunk/extensions/QPoll/qp_user.php
@@ -329,7 +329,7 @@
330330 'qp_user.php' => 'qp_Setup',
331331 'includes/qp_functionshook.php' => 'qp_FunctionsHook',
332332 'includes/qp_renderer.php' => 'qp_Renderer',
333 - 'includes/qp_excel.php' => 'qp_Excel',
 333+ 'includes/qp_xlswriter.php' => 'qp_XlsWriter',
334334
335335 ## DB schema updater
336336 'maintenance/qp_schemaupdater.php' => 'qp_SchemaUpdater',
@@ -371,6 +371,10 @@
372372 ## question data views are used to display question results in Special:PollResults page
373373 'view/results/qp_questiondataresults.php' => 'qp_QuestionDataResults',
374374 'view/results/qp_textquestiondataresults.php' => 'qp_TextQuestionDataResults',
 375+ ## exporting results into XLS format
 376+ 'view/xls/qp_xlspoll.php' => 'qp_XlsPoll',
 377+ 'view/xls/qp_xlstabularquestion.php' => 'qp_XlsTabularQuestion',
 378+ 'view/xls/qp_xlstextquestion.php' => 'qp_XlsTextQuestion',
375379 # interpretation results
376380 'view/qp_interpresultview.php' => 'qp_InterpResultView',
377381
Index: trunk/extensions/QPoll/includes/qp_excel.php
@@ -1,278 +0,0 @@
2 -<?php
3 -/**
4 - * ***** BEGIN LICENSE BLOCK *****
5 - * This file is part of QPoll.
6 - * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved.
7 - *
8 - * QPoll is free software; you can redistribute it and/or modify
9 - * it under the terms of the GNU General Public License as published by
10 - * the Free Software Foundation; either version 2 of the License, or
11 - * (at your option) any later version.
12 - *
13 - * QPoll is distributed in the hope that it will be useful,
14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 - * GNU General Public License for more details.
17 - *
18 - * You should have received a copy of the GNU General Public License
19 - * along with QPoll; if not, write to the Free Software
20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 - *
22 - * ***** END LICENSE BLOCK *****
23 - *
24 - * QPoll is a poll tool for MediaWiki.
25 - *
26 - * To activate this extension :
27 - * * Create a new directory named QPoll into the directory "extensions" of MediaWiki.
28 - * * Place the files from the extension archive there.
29 - * * Add this line at the end of your LocalSettings.php file :
30 - * require_once "$IP/extensions/QPoll/qp_user.php";
31 - *
32 - * @version 0.8.0a
33 - * @link http://www.mediawiki.org/wiki/Extension:QPoll
34 - * @author QuestPC <questpc@rambler.ru>
35 - */
36 -
37 -if ( !defined( 'MEDIAWIKI' ) ) {
38 - die( "This file is part of the QPoll extension. It is not a valid entry point.\n" );
39 -}
40 -
41 -/**
42 - * PEAR Excel helper / wrapper
43 - *
44 - */
45 -class qp_Excel {
46 -
47 - # an instance of XLS worksheet
48 - var $ws;
49 - # list of formats added to workbook
50 - var $format;
51 - # current row number in a worksheet
52 - var $rownum = 0;
53 -
54 - static function newFromWorksheet( Spreadsheet_Excel_Writer_Worksheet $worksheet ) {
55 - $self = new self();
56 - $self->ws = $worksheet;
57 - $self->ws->setInputEncoding( "utf-8" );
58 - $self->ws->setPaper( 9 );
59 - return $self;
60 - }
61 -
62 - static function prepareExcelString( $s ) {
63 - if ( preg_match( '`^=.?`', $s ) ) {
64 - return "'" . $s;
65 - }
66 - return $s;
67 - }
68 -
69 - function writeFormattedTable( $colnum, &$table, $format = null ) {
70 - $ws = $this->ws;
71 - foreach ( $table as $rnum => &$row ) {
72 - foreach ( $row as $cnum => &$cell ) {
73 - if ( is_array( $cell ) ) {
74 - if ( array_key_exists( "format", $cell ) ) {
75 - $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell[ 0 ], $cell[ "format" ] );
76 - } else {
77 - $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell[ 0 ], $format );
78 - }
79 - } else {
80 - $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell, $format );
81 - }
82 - }
83 - }
84 - }
85 -
86 - function writeHeader( $totalUsersAnsweredQuestion ) {
87 - $this->ws->write( $this->rownum, 0, $totalUsersAnsweredQuestion, $this->format['heading'] );
88 - $this->ws->write( $this->rownum++, 1, wfMsgExt( 'qp_users_answered_questions', array( 'parsemag' ), $totalUsersAnsweredQuestion ), $this->format['heading'] );
89 - $this->rownum++;
90 - }
91 -
92 - function voicesToXls( $format, qp_PollStore $pollStore ) {
93 - $this->format = &$format;
94 - $pollStore->loadQuestions();
95 - $ws = $this->ws;
96 - $first_question = true;
97 - foreach ( $pollStore->Questions as $qkey => &$qdata ) {
98 - if ( $first_question ) {
99 - $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
100 - } else {
101 - # get maximum count of voters of the first question
102 - $total_voters = $first_question_voters;
103 - }
104 - $ws->write( $this->rownum, 0, $qdata->question_id, $format['heading'] );
105 - $ws->write( $this->rownum++, 1, self::prepareExcelString( $qdata->CommonQuestion ), $format['heading'] );
106 - if ( count( $qdata->CategorySpans ) > 0 ) {
107 - $row = array();
108 - foreach ( $qdata->CategorySpans as &$span ) {
109 - $row[] = self::prepareExcelString( $span[ "name" ] );
110 - for ( $i = 1; $i < $span[ "count" ]; $i++ ) {
111 - $row[] = "";
112 - }
113 - }
114 - $ws->writerow( $this->rownum++, 0, $row );
115 - }
116 - $row = array();
117 - foreach ( $qdata->Categories as &$categ ) {
118 - $row[] = self::prepareExcelString( $categ[ "name" ] );
119 - }
120 - $ws->writerow( $this->rownum++, 0, $row );
121 -/*
122 - foreach ( $qdata->Percents as $pkey=>&$percent ) {
123 - $ws->writerow( $this->rownum + $pkey, 0, $percent );
124 - }
125 -*/
126 - $voters = array();
127 - $offset = 0;
128 - $spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == "multipleChoice";
129 - # iterate through the voters of the current poll (there might be many)
130 - while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
131 - if ( !$first_question ) {
132 - # do not export more user voices than first question has
133 - for ( $total_voters -= $limit; $total_voters < 0 && $limit > 0; $total_voters++, $limit-- ) {
134 - array_pop( $voters );
135 - }
136 - if ( count( $voters ) === 0 ) {
137 - break;
138 - }
139 - }
140 - $uvoices = $pollStore->questionVoicesRange( $qdata->question_id, array_keys( $voters ) );
141 - # get each of proposal votes for current uid
142 - foreach ( $uvoices as $uid => &$pvoices ) {
143 - # output square table of proposal / category answers for each uid in uvoices array
144 - $voicesTable = array();
145 - foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
146 - $row = array_fill( 0, count( $qdata->Categories ), '' );
147 - if ( isset( $pvoices[$propkey] ) ) {
148 - foreach ( $pvoices[$propkey] as $catkey => $text_answer ) {
149 - $row[$catkey] = self::prepareExcelString( $text_answer );
150 - }
151 - if ( $spansUsed ) {
152 - foreach ( $row as $catkey => &$cell ) {
153 - $cell = array( 0 => $cell );
154 - if ( $qdata->type == "multipleChoice" ) {
155 - $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? $format['even'] : $format['odd'];
156 - } else {
157 - $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? $format['even'] : $format['odd'];
158 - }
159 - }
160 - }
161 - }
162 - $voicesTable[] = $row;
163 - }
164 - $this->writeFormattedTable( 0, $voicesTable, $format['answer'] );
165 - $row = array();
166 - foreach ( $qdata->ProposalText as $ptext ) {
167 - $row[] = self::prepareExcelString( $ptext );
168 - }
169 - $ws->writecol( $this->rownum, count( $qdata->Categories ), $row );
170 - $this->rownum += count( $qdata->ProposalText ) + 1;
171 - }
172 - if ( !$first_question && $total_voters < 1 ) {
173 - # break on reaching the count of first question user voices
174 - break;
175 - }
176 - $offset += $limit;
177 - }
178 - if ( $first_question ) {
179 - # store maximum count of voters of the first question
180 - $first_question_voters = $offset;
181 - $first_question = false;
182 - }
183 - }
184 - }
185 -
186 - function statsToXls( $format, qp_PollStore $pollStore ) {
187 - $this->format = &$format;
188 - $pollStore->loadQuestions();
189 - $pollStore->loadTotals();
190 - $pollStore->calculateStatistics();
191 - $ws = $this->ws;
192 - $first_question = true;
193 - foreach ( $pollStore->Questions as $qkey => &$qdata ) {
194 - if ( $first_question ) {
195 - $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
196 - $first_question = false;
197 - }
198 - $ws->write( $this->rownum, 0, $qdata->question_id, $format['heading'] );
199 - $ws->write( $this->rownum++, 1, self::prepareExcelString( $qdata->CommonQuestion ), $format['heading'] );
200 - if ( count( $qdata->CategorySpans ) > 0 ) {
201 - $row = array();
202 - foreach ( $qdata->CategorySpans as &$span ) {
203 - $row[] = self::prepareExcelString( $span[ "name" ] );
204 - for ( $i = 1; $i < $span[ "count" ]; $i++ ) {
205 - $row[] = "";
206 - }
207 - }
208 - $ws->writerow( $this->rownum++, 0, $row );
209 - }
210 - $row = array();
211 - foreach ( $qdata->Categories as &$categ ) {
212 - $row[] = self::prepareExcelString( $categ[ "name" ] );
213 - }
214 - $ws->writerow( $this->rownum++, 0, $row );
215 -/*
216 - foreach ( $qdata->Percents as $pkey=>&$percent ) {
217 - $ws->writerow( $this->rownum + $pkey, 0, $percent );
218 - }
219 -*/
220 - $percentsTable = array();
221 - $spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == "multipleChoice";
222 - foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
223 - if ( isset( $qdata->Percents[ $propkey ] ) ) {
224 - $row = $qdata->Percents[ $propkey ];
225 - foreach ( $row as $catkey => &$cell ) {
226 - $cell = array( 0 => $cell );
227 - if ( $spansUsed ) {
228 - if ( $qdata->type == "multipleChoice" ) {
229 - $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? $format['even'] : $format['odd'];
230 - } else {
231 - $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? $format['even'] : $format['odd'];
232 - }
233 - }
234 - }
235 - } else {
236 - $row = array_fill( 0, count( $qdata->Categories ), '' );
237 - }
238 - $percentsTable[] = $row;
239 - }
240 - $this->writeFormattedTable( 0, $percentsTable, $format['percent'] );
241 - $row = array();
242 - foreach ( $qdata->ProposalText as $ptext ) {
243 - $row[] = self::prepareExcelString( $ptext );
244 - }
245 - $ws->writecol( $this->rownum, count( $qdata->Categories ), $row );
246 - $this->rownum += count( $qdata->ProposalText ) + 1;
247 - }
248 - }
249 -
250 - function interpretationToXLS( $format, qp_PollStore $pollStore ) {
251 - $offset = 0;
252 - $ws = $this->ws;
253 - # iterate through the voters of the current poll (there might be many)
254 - while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
255 - foreach ( $voters as &$voter ) {
256 - if ( $voter['interpretation']->short != '' ) {
257 - $ws->write( $this->rownum++, 0, self::prepareExcelString( wfMsg( 'qp_results_short_interpretation' ) ), $format['heading'] );
258 - $ws->write( $this->rownum++, 0, self::prepareExcelString( $voter['interpretation']->short ) );
259 - }
260 - if ( $voter['interpretation']->structured != '' ) {
261 - $ws->write( $this->rownum++, 0, self::prepareExcelString( wfMsg( 'qp_results_structured_interpretation' ) ), $format['heading'] );
262 - $strucTable = $voter['interpretation']->getStructuredAnswerTable();
263 - foreach ( $strucTable as &$line ) {
264 - if ( isset( $line['keys'] ) ) {
265 - # current node is associative array
266 - $ws->writeRow( $this->rownum++, 0, $line['keys'], $format['odd'] );
267 - $ws->writeRow( $this->rownum++, 0, $line['vals'] );
268 - } else {
269 - $ws->write( $this->rownum++, 0, $line['vals'] );
270 - }
271 - }
272 - $this->rownum++;
273 - }
274 - }
275 - $offset += $limit;
276 - }
277 - }
278 -
279 -} /* end of qp_Excel class */
Index: trunk/extensions/QPoll/includes/qp_xlswriter.php
@@ -0,0 +1,278 @@
 2+<?php
 3+/**
 4+ * ***** BEGIN LICENSE BLOCK *****
 5+ * This file is part of QPoll.
 6+ * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved.
 7+ *
 8+ * QPoll is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * QPoll is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License
 19+ * along with QPoll; if not, write to the Free Software
 20+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 21+ *
 22+ * ***** END LICENSE BLOCK *****
 23+ *
 24+ * QPoll is a poll tool for MediaWiki.
 25+ *
 26+ * To activate this extension :
 27+ * * Create a new directory named QPoll into the directory "extensions" of MediaWiki.
 28+ * * Place the files from the extension archive there.
 29+ * * Add this line at the end of your LocalSettings.php file :
 30+ * require_once "$IP/extensions/QPoll/qp_user.php";
 31+ *
 32+ * @version 0.8.0a
 33+ * @link http://www.mediawiki.org/wiki/Extension:QPoll
 34+ * @author QuestPC <questpc@rambler.ru>
 35+ */
 36+
 37+if ( !defined( 'MEDIAWIKI' ) ) {
 38+ die( "This file is part of the QPoll extension. It is not a valid entry point.\n" );
 39+}
 40+
 41+/**
 42+ * PEAR Excel helper / wrapper
 43+ *
 44+ */
 45+class qp_Excel {
 46+
 47+ # an instance of XLS worksheet
 48+ var $ws;
 49+ # list of formats added to workbook
 50+ var $format;
 51+ # current row number in a worksheet
 52+ var $rownum = 0;
 53+
 54+ static function newFromWorksheet( Spreadsheet_Excel_Writer_Worksheet $worksheet ) {
 55+ $self = new self();
 56+ $self->ws = $worksheet;
 57+ $self->ws->setInputEncoding( "utf-8" );
 58+ $self->ws->setPaper( 9 );
 59+ return $self;
 60+ }
 61+
 62+ static function prepareExcelString( $s ) {
 63+ if ( preg_match( '`^=.?`', $s ) ) {
 64+ return "'" . $s;
 65+ }
 66+ return $s;
 67+ }
 68+
 69+ function writeFormattedTable( $colnum, &$table, $format = null ) {
 70+ $ws = $this->ws;
 71+ foreach ( $table as $rnum => &$row ) {
 72+ foreach ( $row as $cnum => &$cell ) {
 73+ if ( is_array( $cell ) ) {
 74+ if ( array_key_exists( "format", $cell ) ) {
 75+ $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell[ 0 ], $cell[ "format" ] );
 76+ } else {
 77+ $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell[ 0 ], $format );
 78+ }
 79+ } else {
 80+ $ws->write( $this->rownum + $rnum, $colnum + $cnum, $cell, $format );
 81+ }
 82+ }
 83+ }
 84+ }
 85+
 86+ function writeHeader( $totalUsersAnsweredQuestion ) {
 87+ $this->ws->write( $this->rownum, 0, $totalUsersAnsweredQuestion, $this->format['heading'] );
 88+ $this->ws->write( $this->rownum++, 1, wfMsgExt( 'qp_users_answered_questions', array( 'parsemag' ), $totalUsersAnsweredQuestion ), $this->format['heading'] );
 89+ $this->rownum++;
 90+ }
 91+
 92+ function voicesToXls( $format, qp_PollStore $pollStore ) {
 93+ $this->format = &$format;
 94+ $pollStore->loadQuestions();
 95+ $ws = $this->ws;
 96+ $first_question = true;
 97+ foreach ( $pollStore->Questions as $qkey => &$qdata ) {
 98+ if ( $first_question ) {
 99+ $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
 100+ } else {
 101+ # get maximum count of voters of the first question
 102+ $total_voters = $first_question_voters;
 103+ }
 104+ $ws->write( $this->rownum, 0, $qdata->question_id, $format['heading'] );
 105+ $ws->write( $this->rownum++, 1, self::prepareExcelString( $qdata->CommonQuestion ), $format['heading'] );
 106+ if ( count( $qdata->CategorySpans ) > 0 ) {
 107+ $row = array();
 108+ foreach ( $qdata->CategorySpans as &$span ) {
 109+ $row[] = self::prepareExcelString( $span[ "name" ] );
 110+ for ( $i = 1; $i < $span[ "count" ]; $i++ ) {
 111+ $row[] = "";
 112+ }
 113+ }
 114+ $ws->writerow( $this->rownum++, 0, $row );
 115+ }
 116+ $row = array();
 117+ foreach ( $qdata->Categories as &$categ ) {
 118+ $row[] = self::prepareExcelString( $categ[ "name" ] );
 119+ }
 120+ $ws->writerow( $this->rownum++, 0, $row );
 121+/*
 122+ foreach ( $qdata->Percents as $pkey=>&$percent ) {
 123+ $ws->writerow( $this->rownum + $pkey, 0, $percent );
 124+ }
 125+*/
 126+ $voters = array();
 127+ $offset = 0;
 128+ $spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == "multipleChoice";
 129+ # iterate through the voters of the current poll (there might be many)
 130+ while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
 131+ if ( !$first_question ) {
 132+ # do not export more user voices than first question has
 133+ for ( $total_voters -= $limit; $total_voters < 0 && $limit > 0; $total_voters++, $limit-- ) {
 134+ array_pop( $voters );
 135+ }
 136+ if ( count( $voters ) === 0 ) {
 137+ break;
 138+ }
 139+ }
 140+ $uvoices = $pollStore->questionVoicesRange( $qdata->question_id, array_keys( $voters ) );
 141+ # get each of proposal votes for current uid
 142+ foreach ( $uvoices as $uid => &$pvoices ) {
 143+ # output square table of proposal / category answers for each uid in uvoices array
 144+ $voicesTable = array();
 145+ foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
 146+ $row = array_fill( 0, count( $qdata->Categories ), '' );
 147+ if ( isset( $pvoices[$propkey] ) ) {
 148+ foreach ( $pvoices[$propkey] as $catkey => $text_answer ) {
 149+ $row[$catkey] = self::prepareExcelString( $text_answer );
 150+ }
 151+ if ( $spansUsed ) {
 152+ foreach ( $row as $catkey => &$cell ) {
 153+ $cell = array( 0 => $cell );
 154+ if ( $qdata->type == "multipleChoice" ) {
 155+ $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? $format['even'] : $format['odd'];
 156+ } else {
 157+ $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? $format['even'] : $format['odd'];
 158+ }
 159+ }
 160+ }
 161+ }
 162+ $voicesTable[] = $row;
 163+ }
 164+ $this->writeFormattedTable( 0, $voicesTable, $format['answer'] );
 165+ $row = array();
 166+ foreach ( $qdata->ProposalText as $ptext ) {
 167+ $row[] = self::prepareExcelString( $ptext );
 168+ }
 169+ $ws->writecol( $this->rownum, count( $qdata->Categories ), $row );
 170+ $this->rownum += count( $qdata->ProposalText ) + 1;
 171+ }
 172+ if ( !$first_question && $total_voters < 1 ) {
 173+ # break on reaching the count of first question user voices
 174+ break;
 175+ }
 176+ $offset += $limit;
 177+ }
 178+ if ( $first_question ) {
 179+ # store maximum count of voters of the first question
 180+ $first_question_voters = $offset;
 181+ $first_question = false;
 182+ }
 183+ }
 184+ }
 185+
 186+ function statsToXls( $format, qp_PollStore $pollStore ) {
 187+ $this->format = &$format;
 188+ $pollStore->loadQuestions();
 189+ $pollStore->loadTotals();
 190+ $pollStore->calculateStatistics();
 191+ $ws = $this->ws;
 192+ $first_question = true;
 193+ foreach ( $pollStore->Questions as $qkey => &$qdata ) {
 194+ if ( $first_question ) {
 195+ $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
 196+ $first_question = false;
 197+ }
 198+ $ws->write( $this->rownum, 0, $qdata->question_id, $format['heading'] );
 199+ $ws->write( $this->rownum++, 1, self::prepareExcelString( $qdata->CommonQuestion ), $format['heading'] );
 200+ if ( count( $qdata->CategorySpans ) > 0 ) {
 201+ $row = array();
 202+ foreach ( $qdata->CategorySpans as &$span ) {
 203+ $row[] = self::prepareExcelString( $span[ "name" ] );
 204+ for ( $i = 1; $i < $span[ "count" ]; $i++ ) {
 205+ $row[] = "";
 206+ }
 207+ }
 208+ $ws->writerow( $this->rownum++, 0, $row );
 209+ }
 210+ $row = array();
 211+ foreach ( $qdata->Categories as &$categ ) {
 212+ $row[] = self::prepareExcelString( $categ[ "name" ] );
 213+ }
 214+ $ws->writerow( $this->rownum++, 0, $row );
 215+/*
 216+ foreach ( $qdata->Percents as $pkey=>&$percent ) {
 217+ $ws->writerow( $this->rownum + $pkey, 0, $percent );
 218+ }
 219+*/
 220+ $percentsTable = array();
 221+ $spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == "multipleChoice";
 222+ foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
 223+ if ( isset( $qdata->Percents[ $propkey ] ) ) {
 224+ $row = $qdata->Percents[ $propkey ];
 225+ foreach ( $row as $catkey => &$cell ) {
 226+ $cell = array( 0 => $cell );
 227+ if ( $spansUsed ) {
 228+ if ( $qdata->type == "multipleChoice" ) {
 229+ $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? $format['even'] : $format['odd'];
 230+ } else {
 231+ $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? $format['even'] : $format['odd'];
 232+ }
 233+ }
 234+ }
 235+ } else {
 236+ $row = array_fill( 0, count( $qdata->Categories ), '' );
 237+ }
 238+ $percentsTable[] = $row;
 239+ }
 240+ $this->writeFormattedTable( 0, $percentsTable, $format['percent'] );
 241+ $row = array();
 242+ foreach ( $qdata->ProposalText as $ptext ) {
 243+ $row[] = self::prepareExcelString( $ptext );
 244+ }
 245+ $ws->writecol( $this->rownum, count( $qdata->Categories ), $row );
 246+ $this->rownum += count( $qdata->ProposalText ) + 1;
 247+ }
 248+ }
 249+
 250+ function interpretationToXLS( $format, qp_PollStore $pollStore ) {
 251+ $offset = 0;
 252+ $ws = $this->ws;
 253+ # iterate through the voters of the current poll (there might be many)
 254+ while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
 255+ foreach ( $voters as &$voter ) {
 256+ if ( $voter['interpretation']->short != '' ) {
 257+ $ws->write( $this->rownum++, 0, self::prepareExcelString( wfMsg( 'qp_results_short_interpretation' ) ), $format['heading'] );
 258+ $ws->write( $this->rownum++, 0, self::prepareExcelString( $voter['interpretation']->short ) );
 259+ }
 260+ if ( $voter['interpretation']->structured != '' ) {
 261+ $ws->write( $this->rownum++, 0, self::prepareExcelString( wfMsg( 'qp_results_structured_interpretation' ) ), $format['heading'] );
 262+ $strucTable = $voter['interpretation']->getStructuredAnswerTable();
 263+ foreach ( $strucTable as &$line ) {
 264+ if ( isset( $line['keys'] ) ) {
 265+ # current node is associative array
 266+ $ws->writeRow( $this->rownum++, 0, $line['keys'], $format['odd'] );
 267+ $ws->writeRow( $this->rownum++, 0, $line['vals'] );
 268+ } else {
 269+ $ws->write( $this->rownum++, 0, $line['vals'] );
 270+ }
 271+ }
 272+ $this->rownum++;
 273+ }
 274+ }
 275+ $offset += $limit;
 276+ }
 277+ }
 278+
 279+} /* end of qp_Excel class */
Property changes on: trunk/extensions/QPoll/includes/qp_xlswriter.php
___________________________________________________________________
Added: svn:eol-style
1280 + native
Index: trunk/extensions/QPoll/view/xls/qp_xlstabularquestion.php
@@ -0,0 +1,95 @@
 2+<?php
 3+
 4+class qp_XlsTabularQuestion extends qp_XlsWriter {
 5+
 6+ var $qdata;
 7+
 8+ var $spansUsed;
 9+
 10+ function setQuestionData( qp_QuestionData $qdata ) {
 11+ $this->qdata = $qdata;
 12+ $this->spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == 'multipleChoice';
 13+ }
 14+
 15+ function writeHeader() {
 16+ $this->write( 0, $this->qdata->question_id, 'heading' );
 17+ $this->writeLn( 1, $this->qdata->CommonQuestion, 'heading' );
 18+ if ( count( $this->qdata->CategorySpans ) > 0 ) {
 19+ $row = array();
 20+ foreach ( $this->qdata->CategorySpans as &$span ) {
 21+ $row[] = $span['name'];
 22+ for ( $i = 1; $i < $span['count']; $i++ ) {
 23+ $row[] = '';
 24+ }
 25+ }
 26+ $this->writeRowLn( 0, $row );
 27+ }
 28+ $row = array();
 29+ foreach ( $this->qdata->Categories as &$categ ) {
 30+ $row[] = $categ['name'];
 31+ }
 32+ $this->writeRowLn( 0, $row );
 33+ }
 34+
 35+ function writeQuestionVoice( $pvoices ) {
 36+ $qdata = $this->qdata;
 37+ # create square table of proposal / category answers for each uid in uvoices array
 38+ $voicesTable = array();
 39+ foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
 40+ $row = array_fill( 0, count( $qdata->Categories ), '' );
 41+ if ( isset( $pvoices[$propkey] ) ) {
 42+ foreach ( $pvoices[$propkey] as $catkey => $text_answer ) {
 43+ $row[$catkey] = $text_answer;
 44+ }
 45+ if ( $this->spansUsed ) {
 46+ foreach ( $row as $catkey => &$cell ) {
 47+ $cell = array( 0 => $cell );
 48+ if ( $qdata->type == 'multipleChoice' ) {
 49+ $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? 'even' : 'odd';
 50+ } else {
 51+ $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? 'even' : 'odd';
 52+ }
 53+ }
 54+ }
 55+ }
 56+ $voicesTable[] = $row;
 57+ }
 58+ $this->writeFormattedTable( 0, $voicesTable, 'answer' );
 59+ $row = array();
 60+ foreach ( $qdata->ProposalText as $ptext ) {
 61+ $row[] = $ptext;
 62+ }
 63+ $this->writeCol( count( $qdata->Categories ), $row );
 64+ $this->relRow( count( $qdata->ProposalText ) + 1 );
 65+ }
 66+
 67+ function writeQuestionStats() {
 68+ $qdata = $this->qdata;
 69+ foreach ( $qdata->ProposalText as $propkey => &$proposal_text ) {
 70+ if ( isset( $qdata->Percents[ $propkey ] ) ) {
 71+ $row = $qdata->Percents[ $propkey ];
 72+ foreach ( $row as $catkey => &$cell ) {
 73+ $cell = array( 0 => $cell );
 74+ if ( $this->spansUsed ) {
 75+ if ( $qdata->type == 'multipleChoice' ) {
 76+ $cell['format'] = ( ( $catkey & 1 ) === 0 ) ? 'even' : 'odd';
 77+ } else {
 78+ $cell['format'] = ( ( $qdata->Categories[ $catkey ][ "spanId" ] & 1 ) === 0 ) ? 'even' : 'odd';
 79+ }
 80+ }
 81+ }
 82+ } else {
 83+ $row = array_fill( 0, count( $qdata->Categories ), '' );
 84+ }
 85+ $percentsTable[] = $row;
 86+ }
 87+ $this->writeFormattedTable( 0, $percentsTable, 'percent' );
 88+ $row = array();
 89+ foreach ( $qdata->ProposalText as $ptext ) {
 90+ $row[] = $ptext;
 91+ }
 92+ $this->writeCol( count( $qdata->Categories ), $row );
 93+ $this->relRow( count( $qdata->ProposalText ) + 1 );
 94+ }
 95+
 96+} /* end of qp_XlsTabularQuestion class */
Property changes on: trunk/extensions/QPoll/view/xls/qp_xlstabularquestion.php
___________________________________________________________________
Added: svn:eol-style
197 + native
Index: trunk/extensions/QPoll/view/xls/qp_xlspoll.php
@@ -0,0 +1,160 @@
 2+<?php
 3+/**
 4+ * ***** BEGIN LICENSE BLOCK *****
 5+ * This file is part of QPoll.
 6+ * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved.
 7+ *
 8+ * QPoll is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * QPoll is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License
 19+ * along with QPoll; if not, write to the Free Software
 20+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 21+ *
 22+ * ***** END LICENSE BLOCK *****
 23+ *
 24+ * QPoll is a poll tool for MediaWiki.
 25+ *
 26+ * To activate this extension :
 27+ * * Create a new directory named QPoll into the directory "extensions" of MediaWiki.
 28+ * * Place the files from the extension archive there.
 29+ * * Add this line at the end of your LocalSettings.php file :
 30+ * require_once "$IP/extensions/QPoll/qp_user.php";
 31+ *
 32+ * @version 0.8.0a
 33+ * @link http://www.mediawiki.org/wiki/Extension:QPoll
 34+ * @author QuestPC <questpc@rambler.ru>
 35+ */
 36+
 37+if ( !defined( 'MEDIAWIKI' ) ) {
 38+ die( "This file is part of the QPoll extension. It is not a valid entry point.\n" );
 39+}
 40+
 41+/**
 42+ * PEAR Excel helper / wrapper
 43+ *
 44+ */
 45+class qp_XlsPoll extends qp_XlsWriter {
 46+
 47+ var $tabular_writer;
 48+ var $text_writer;
 49+
 50+ function __construct( $xls_fname = null ) {
 51+ parent::__construct( $xls_fname );
 52+ # Create question writers; Single instances will be re-used in the top loop.
 53+ # They are sharing the same instance of Spreadsheet_Excel_Writer_Worksheet.
 54+ # We do not use class with static properties and methods only because
 55+ # such class names cannot be accessed by reference in PHP < 5.3.0:
 56+ # http://php.net/manual/en/language.oop5.static.php
 57+ # "As of PHP 5.3.0, it's possible to reference the class using a variable.
 58+ # The variable's value can not be a keyword (e.g. self, parent and static)."
 59+ $this->tabular_writer = new qp_XlsTabularQuestion();
 60+ $this->text_writer = new qp_XlsTextQuestion();
 61+ }
 62+
 63+ function writeHeader( $totalUsersAnsweredQuestion ) {
 64+ $this->write( 0, $totalUsersAnsweredQuestion, 'heading' );
 65+ $this->writeLn( 1, wfMsgExt( 'qp_users_answered_questions', array( 'parsemag' ), $totalUsersAnsweredQuestion ), 'heading' );
 66+ $this->nextRow();
 67+ }
 68+
 69+ function voicesToXls( qp_PollStore $pollStore ) {
 70+ $pollStore->loadQuestions();
 71+ $first_question = true;
 72+ foreach ( $pollStore->Questions as $qkey => &$qdata ) {
 73+ $xlsq = ( $qdata->type === 'textQuestion' ) ? $this->text_writer : $this->tabular_writer;
 74+ $xlsq->setQuestionData( $qdata );
 75+ if ( $first_question ) {
 76+ $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
 77+ } else {
 78+ # get maximum count of voters of the first question
 79+ $total_voters = $first_question_voters;
 80+ }
 81+ $xlsq->writeHeader();
 82+ $voters = array();
 83+ $offset = 0;
 84+ # iterate through the voters of the current poll (there might be many)
 85+ while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
 86+ if ( !$first_question ) {
 87+ # do not export more user voices than first question has
 88+ for ( $total_voters -= $limit; $total_voters < 0 && $limit > 0; $total_voters++, $limit-- ) {
 89+ array_pop( $voters );
 90+ }
 91+ if ( count( $voters ) === 0 ) {
 92+ break;
 93+ }
 94+ }
 95+ $uvoices = $pollStore->questionVoicesRange( $qdata->question_id, array_keys( $voters ) );
 96+ # get each of proposal votes for current uid
 97+ foreach ( $uvoices as $uid => &$pvoices ) {
 98+ $xlsq->writeQuestionVoice( $pvoices );
 99+ }
 100+ if ( !$first_question && $total_voters < 1 ) {
 101+ # break on reaching the count of first question user voices
 102+ break;
 103+ }
 104+ $offset += $limit;
 105+ }
 106+ if ( $first_question ) {
 107+ # store maximum count of voters of the first question
 108+ $first_question_voters = $offset;
 109+ $first_question = false;
 110+ }
 111+ }
 112+ }
 113+
 114+ function statsToXls( qp_PollStore $pollStore ) {
 115+ $pollStore->loadQuestions();
 116+ $pollStore->loadTotals();
 117+ $pollStore->calculateStatistics();
 118+ $first_question = true;
 119+ foreach ( $pollStore->Questions as $qkey => &$qdata ) {
 120+ $xlsq = ( $qdata->type === 'textQuestion' ) ? $this->text_writer : $this->tabular_writer;
 121+ $xlsq->setQuestionData( $qdata );
 122+ if ( $first_question ) {
 123+ $this->writeHeader( $pollStore->totalUsersAnsweredQuestion( $qdata ) );
 124+ $first_question = false;
 125+ }
 126+ $xlsq->writeHeader();
 127+ $percentsTable = array();
 128+ $spansUsed = count( $qdata->CategorySpans ) > 0 || $qdata->type == "multipleChoice";
 129+ $xlsq->writeQuestionStats();
 130+ }
 131+ }
 132+
 133+ function interpretationToXLS( qp_PollStore $pollStore ) {
 134+ $offset = 0;
 135+ # iterate through the voters of the current poll (there might be many)
 136+ while ( ( $limit = count( $voters = $pollStore->pollVotersPager( $offset ) ) ) > 0 ) {
 137+ foreach ( $voters as &$voter ) {
 138+ if ( $voter['interpretation']->short != '' ) {
 139+ $this->writeLn( 0, wfMsg( 'qp_results_short_interpretation' ), 'heading' );
 140+ $this->writeLn( 0, $voter['interpretation']->short );
 141+ }
 142+ if ( $voter['interpretation']->structured != '' ) {
 143+ $this->writeLn( 0, wfMsg( 'qp_results_structured_interpretation' ), 'heading' );
 144+ $strucTable = $voter['interpretation']->getStructuredAnswerTable();
 145+ foreach ( $strucTable as &$line ) {
 146+ if ( isset( $line['keys'] ) ) {
 147+ # current node is associative array
 148+ $this->writeRowLn( 0, $line['keys'], 'odd' );
 149+ $ws->writeRowLn( 0, $line['vals'] );
 150+ } else {
 151+ $this->writeLn( 0, $line['vals'] );
 152+ }
 153+ }
 154+ $this->nextRow();
 155+ }
 156+ }
 157+ $offset += $limit;
 158+ }
 159+ }
 160+
 161+} /* end of qp_XlsPoll class */
Property changes on: trunk/extensions/QPoll/view/xls/qp_xlspoll.php
___________________________________________________________________
Added: svn:eol-style
1162 + native
Index: trunk/extensions/QPoll/view/xls/qp_xlstextquestion.php
@@ -0,0 +1,78 @@
 2+<?php
 3+
 4+class qp_XlsTextQuestion extends qp_XlsTabularQuestion {
 5+
 6+ function __construct( $xls_fname = null ) {
 7+ parent::__construct( $xls_fname );
 8+ $this->addFormats( array(
 9+ 'cat_part' => array( 'fgcolor' => 36, 'border' => 1 ),
 10+ 'prop_part' => array( 'fgcolor' => 34, 'border' => 1 ),
 11+ ) );
 12+ }
 13+
 14+ function writeQuestionVoice( $pvoices ) {
 15+ $qdata = $this->qdata;
 16+ foreach ( $qdata->ProposalText as $propkey => &$serialized_tokens ) {
 17+ # Create 2D-table of proposal / category answers for each uid in uvoices array
 18+ # please note that for text question array may be sparce (not rectangular)
 19+ $voicesTable = array();
 20+ # voicesTable row number
 21+ $rowNum = 0;
 22+ if ( !is_array( $dbtokens = unserialize( $serialized_tokens ) ) ) {
 23+ throw new MWException( 'dbtokens is not an array in ' . __METHOD__ );
 24+ }
 25+ $catId = 0;
 26+ if ( ( $hasVoices = isset( $pvoices[$propkey] ) ) ) {
 27+ $pv = &$pvoices[$propkey];
 28+ }
 29+ $voicesTable[$rowNum] = array();
 30+ # voicesTable column number
 31+ $rowCol = 0;
 32+ # height of current proposal row (may be greater than 1 when more than one text option was selected by user)
 33+ $rowHeight = 1;
 34+ foreach ( $dbtokens as &$token ) {
 35+ if ( is_string( $token ) ) {
 36+ # add a proposal part
 37+ $voicesTable[$rowNum][$rowCol++] = array( $token, 'format' => 'prop_part' );
 38+ } elseif ( is_array( $token ) ) {
 39+ # add a category definition with selected text answer (if any)
 40+ if ( $hasVoices && isset( $pv[$catId] ) ) {
 41+ if ( $pv[$catId] !== '' ) {
 42+ # text answer
 43+ $selected_options = explode( qp_Setup::SELECT_MULTIPLE_VALUES_SEPARATOR, $pv[$catId] );
 44+ if ( count( $selected_options ) > 1 ) {
 45+ $saveRowNum = $rowNum;
 46+ foreach ( $selected_options as $option ) {
 47+ if ( !array_key_exists( $rowNum, $voicesTable ) ) {
 48+ $voicesTable[$rowNum] = array();
 49+ }
 50+ $voicesTable[$rowNum++][$rowCol] = array( $option, 'format' => 'cat_part' );
 51+ }
 52+ $rowCol++;
 53+ if ( ( $rowNum - $saveRowNum ) > $rowHeight ) {
 54+ $rowHeight = $rowNum - $saveRowNum;
 55+ }
 56+ $rowNum = $saveRowNum;
 57+ } else {
 58+ $voicesTable[$rowNum][$rowCol++] = array( array_pop( $selected_options ), 'format' => 'cat_part' );
 59+ }
 60+ } else {
 61+ # checkbox or radiobutton
 62+ $voicesTable[$rowNum][$rowCol++] = array( qp_Setup::RESULTS_CHECK_SIGN, 'format' => 'cat_part' );
 63+ }
 64+ } else {
 65+ # non-selected category (it has no selected option)
 66+ $voicesTable[$rowNum][$rowCol++] = array( '', 'format' => 'cat_part' );
 67+ }
 68+ $catId++;
 69+ } else {
 70+ throw new MWException( 'DB token has invalid type (' . gettype( $token ) . ') in ' . __METHOD__ );
 71+ }
 72+ }
 73+ $this->writeFormattedTable( 0, $voicesTable );
 74+ $this->relRow( $rowHeight );
 75+ }
 76+ $this->nextRow();
 77+ }
 78+
 79+} /* end of qp_XlsTextQuestion class */
Property changes on: trunk/extensions/QPoll/view/xls/qp_xlstextquestion.php
___________________________________________________________________
Added: svn:eol-style
180 + native

Status & tagging log