Index: trunk/extensions/QPoll/i18n/qp.i18n.php |
— | — | @@ -121,7 +121,9 @@ |
122 | 122 | 'qp_error_non_unique_choice' => 'This question requires unique proposal answer.', |
123 | 123 | 'qp_error_category_name_empty' => 'Category name is empty.', |
124 | 124 | 'qp_error_proposal_text_empty' => 'Proposal text is empty.', |
125 | | - 'qp_error_too_long_proposal_text' => 'Proposal text is too long to be stored in the database', |
| 125 | + 'qp_error_too_long_category_option_value' => 'Category option value is too long to be stored in the database.', |
| 126 | + 'qp_error_too_long_category_options_values' => 'Category options values are too long to be stored in the database.', |
| 127 | + 'qp_error_too_long_proposal_text' => 'Proposal text is too long to be stored in the database.', |
126 | 128 | 'qp_error_too_few_categories' => 'At least two categories must be defined.', |
127 | 129 | 'qp_error_too_few_spans' => 'Every category group must contain at least two subcategories.', |
128 | 130 | 'qp_error_no_answer' => 'Unanswered proposal.', |
— | — | @@ -235,6 +237,9 @@ |
236 | 238 | * $3 is the poll ID of the poll, which this erroneous poll depends on.', |
237 | 239 | 'qp_error_too_many_spans' => 'There cannot be more category groups defined than the total count of subcategories.', |
238 | 240 | 'qp_error_too_few_spans' => 'Every category group should include at least two subcategories', |
| 241 | + '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.', |
| 242 | + '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.', |
| 243 | + '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.', |
239 | 244 | '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.', |
240 | 245 | 'qp_error_interpretation_no_return' => 'Interpretation script missed an return statement.', |
241 | 246 | 'qp_error_structured_interpretation_is_too_long' => "Structured interpretation is serialized string containing scalar value or an associative array stored into database table field. It's purpose is to have measurable, easily processable interpretation result for the particular poll which then can be processed by external tools (via XLS export) or, to be read and processed by next poll interpretation script (data import and in the future maybe an export as well). When the serialized string is too long, it should never be stored, otherwise it will be truncated by DBMS so it cannot be properly unserialized later.", |
— | — | @@ -2731,6 +2736,8 @@ |
2732 | 2737 | 'qp_error_non_unique_choice' => 'Данный вопрос требует чтобы выбранный вариант ответа не использовался ранее', |
2733 | 2738 | 'qp_error_category_name_empty' => 'Отсутствует название варианта ответа', |
2734 | 2739 | 'qp_error_proposal_text_empty' => 'Отсутствует текст строки вопроса', |
| 2740 | + 'qp_error_too_long_category_option_value' => 'Вариант ответа для данной категории слишком длинный для сохранения в базе данных', |
| 2741 | + 'qp_error_too_long_category_options_values' => 'Варианты ответов для данной категории слишком длинны для сохранения в базе данных', |
2735 | 2742 | 'qp_error_too_long_proposal_text' => 'Строка вопроса слишком длинна для сохранения в базе данных', |
2736 | 2743 | 'qp_error_too_few_categories' => 'Каждый вопрос должен иметь по крайней мере два варианта ответа', |
2737 | 2744 | 'qp_error_too_few_spans' => 'Каждая подкатегория вопроса требует по меньшей мере два варианта ответа', |
Index: trunk/extensions/QPoll/ctrl/question/qp_textquestion.php |
— | — | @@ -12,6 +12,11 @@ |
13 | 13 | |
14 | 14 | # boolean, indicates whether incoming tokens are category list elements |
15 | 15 | var $isCatDef; |
| 16 | + # indicates whether list of select options will fit into DB field or not |
| 17 | + # boolean false the values will fit; |
| 18 | + # int 0 the longest value won't fit; |
| 19 | + # int 1 all the values of select multiple won't fit; |
| 20 | + var $hasOverflow; |
16 | 21 | # type of created element (text,radio,checkbox) |
17 | 22 | var $type; |
18 | 23 | # counter of pipe-separated elements in-between << >> markup |
— | — | @@ -71,6 +76,7 @@ |
72 | 77 | */ |
73 | 78 | function startOptionsList( $type ) { |
74 | 79 | $this->isCatDef = true; |
| 80 | + $this->hasOverflow = false; |
75 | 81 | $this->type = $type; |
76 | 82 | $this->input_options = array( 0 => '' ); |
77 | 83 | $this->hasAttributes = false; |
— | — | @@ -156,6 +162,25 @@ |
157 | 163 | rsort( $this->input_options, SORT_STRING ); |
158 | 164 | break; |
159 | 165 | } |
| 166 | + if ( $this->type === 'text' && count( $this->input_options ) > 1 ) { |
| 167 | + # check max length of select values that may be stored |
| 168 | + # into 'text_answer' DB field |
| 169 | + if ( $this->attributes['multiple'] === null ) { |
| 170 | + # one value may be selected and then submitted |
| 171 | + $multiple = 0; |
| 172 | + $val_max_len = 0; |
| 173 | + foreach ( $this->input_options as $option ) { |
| 174 | + if ( strlen( $option ) > $val_max_len ) { |
| 175 | + $val_max_len= strlen( $option ); |
| 176 | + } |
| 177 | + } |
| 178 | + } else { |
| 179 | + # all of the values may be selected and then submitted |
| 180 | + $multiple = 1; |
| 181 | + $val_max_len = strlen( implode( qp_Setup::SELECT_MULTIPLE_VALUES_SEPARATOR, $this->input_options ) ); |
| 182 | + } |
| 183 | + $this->hasOverflow = ( $val_max_len > qp_Setup::$field_max_len['text_answer'] ) ? $multiple : false; |
| 184 | + } |
160 | 185 | } |
161 | 186 | |
162 | 187 | } /* end of qp_TextQuestionOptions class */ |
— | — | @@ -310,6 +335,10 @@ |
311 | 336 | } |
312 | 337 | # finally, add new category input options for the view |
313 | 338 | $opt->closeCategory(); |
| 339 | + if ( $opt->hasOverflow !== false ) { |
| 340 | + $msg_key = ( $opt->hasOverflow === 0 ) ? 'qp_error_too_long_category_option_value' : 'qp_error_too_long_category_options_values'; |
| 341 | + $this->propview->addErrorToken( wfMsg( $msg_key ), 'error' ); |
| 342 | + } |
314 | 343 | $this->propview->addCatDef( $opt, $name, $text_answer, $this->poll->mBeingCorrected && !$answered ); |
315 | 344 | } |
316 | 345 | |
Index: trunk/extensions/QPoll/qp_user.php |
— | — | @@ -244,15 +244,25 @@ |
245 | 245 | * Otherwise the DB performance may decrease. |
246 | 246 | */ |
247 | 247 | public static $field_max_len = array( |
248 | | - # not larger than DB field size, otherwise checking of dependance chain will fail: |
| 248 | + # 'dependance' is not longer than DB field size (65535), |
| 249 | + # otherwise checking of dependance chain will fail: |
249 | 250 | 'dependance' => 768, |
| 251 | + # limited due to performance improvements (to fit into DB row), |
| 252 | + # and also to properly truncate UFT8 tails: |
250 | 253 | 'common_question' => 768, |
251 | | - # 'proposal_text' length is important for question type="text", where |
252 | | - # proposal text contains serialized array of proposal parts and category fields: |
253 | | - 'proposal_text' => 768, |
| 254 | + # 'proposal_text' is not longer than DB field size (65535), |
| 255 | + # otherwise unserialization of question type="text" proposal parts and |
| 256 | + # category fields will be invalid: |
| 257 | + 'proposal_text' => 1536, |
| 258 | + # 'text_answer' is not longer than DB field size (65535), |
| 259 | + # otherwise question type="text" user-selected select multiple values |
| 260 | + # may be lost: |
254 | 261 | 'text_answer' => 768, |
| 262 | + # limited due to performance improvements (to fit into DB row), |
| 263 | + # and also to properly truncate UFT8 tails: |
255 | 264 | 'long_interpretation' => 768, |
256 | | - # not larger than DB field size, otherwise unserialization will be invalid: |
| 265 | + # 'serialized_interpretation' is not longer than DB field size (65535), |
| 266 | + # otherwise unserialization of structured answer will be invalid: |
257 | 267 | 'serialized_interpretation' => 65535 |
258 | 268 | ); |
259 | 269 | # whether to show short, long, structured interpretation results to end user |
Index: trunk/extensions/QPoll/view/proposal/qp_textquestionproposalview.php |
— | — | @@ -82,22 +82,37 @@ |
83 | 83 | } |
84 | 84 | |
85 | 85 | /** |
86 | | - * Adds new non-empty error message to the list of parsed tokens (viewtokens) |
| 86 | + * Adds new non-empty error message to the begin of the list of parsed tokens (viewtokens) |
87 | 87 | * @param $msg - text of message |
88 | 88 | * @param $state - set new question controller state |
89 | 89 | * note that the 'error' state cannot be changed and '' state cannot be set |
90 | 90 | * @param $rowClass - string set rowClass value, boolean false (do not set) |
91 | 91 | */ |
92 | 92 | function prependErrorToken( $msg, $state, $rowClass = 'proposalerror' ) { |
93 | | - # note: error message also can be added in the middle of the list, |
94 | | - # for any category, if desired, although that is currently not implemented |
95 | 93 | $errmsg = $this->bodyErrorMessage( $msg, $state, $rowClass ); |
96 | 94 | # note: when $state == '' every $errmsg is non-empty; |
97 | 95 | # when $state == 'error' only the first $errmsg is non-empty; |
98 | 96 | if ( $errmsg !== '' ) { |
99 | 97 | array_unshift( $this->viewtokens, (object) array( 'error'=> $errmsg ) ); |
| 98 | + if ( count( $this->viewtokens ) < 2 ) { |
| 99 | + $this->lastTokenType = 'errmsg'; |
| 100 | + } |
100 | 101 | } |
101 | | - if ( count( $this->viewtokens ) < 2 ) { |
| 102 | + } |
| 103 | + |
| 104 | + /** |
| 105 | + * Adds new non-empty error message to the end of the list of parsed tokens (viewtokens) |
| 106 | + * @param $msg - text of message |
| 107 | + * @param $state - set new question controller state |
| 108 | + * note that the 'error' state cannot be changed and '' state cannot be set |
| 109 | + * @param $rowClass - string set rowClass value, boolean false (do not set) |
| 110 | + */ |
| 111 | + function addErrorToken( $msg, $state, $rowClass = 'proposalerror' ) { |
| 112 | + $errmsg = $this->bodyErrorMessage( $msg, $state, $rowClass ); |
| 113 | + # note: when $state == '' every $errmsg is non-empty; |
| 114 | + # when $state == 'error' only the first $errmsg is non-empty; |
| 115 | + if ( $errmsg !== '' ) { |
| 116 | + array_push( $this->viewtokens, (object) array( 'error'=> $errmsg ) ); |
102 | 117 | $this->lastTokenType = 'errmsg'; |
103 | 118 | } |
104 | 119 | } |