/** * Applies interpretation script category error messages * to the current proposal line. * @param $prop_desc array * keys are category numbers (indexes) * values are interpretation script-generated error messages * @return boolean true when at least one category was found in the list * false otherwise */ function applyInterpErrors( array $prop_desc ) { $foundCats = false; # scan the category views row to highlight erroneous categories foreach ( $this->row as $cat_id => &$cat_tag ) { # only integer keys are the category views if ( is_int( $cat_id ) && isset( $prop_desc[$cat_id] ) ) { # found a category which has script-generated error $foundCats = true; # whether to use custom or standard error message if ( !is_string( $cat_desc = $prop_desc[$cat_id] ) ) { $cat_desc = wfMsg( 'qp_interpetation_wrong_answer' ); } # highlight the input qp_Renderer::addClass( $cat_tag, 'cat_error' ); array_unshift( $cat_tag, $this->ctrl->view->bodyErrorMessage( $cat_desc, '', false ) . '<br />' ); } } return $foundCats; }
/** * Creates question view which should be renreded and * also may be altered during the poll generation */ function questionParseBody( $inputType ) { $proposalId = -1; # set static view state for the future qp_TabularQuestionProposalView instances qp_TabularQuestionProposalView::applyViewState( $this->view ); $prop_attrs = qp_Setup::$propAttrs; $prop_attrs->setQuestion( $this ); while ( $prop_attrs->iterate() ) { # new proposal view $pview = new qp_TabularQuestionProposalView( $proposalId + 1, $this ); $proposalId++; $prop_attrs->dbText = $pview->text = $prop_attrs->cpdef; if ( is_string( $prop_attrs->error ) ) { $pview->prependErrorMessage( wfMsg( $prop_attrs->error ), 'error' ); } elseif ( $prop_attrs->name !== '' ) { $this->mProposalNames[$proposalId] = $prop_attrs->name; } $this->mProposalText[$proposalId] = strval( $prop_attrs ); foreach ( $this->mCategories as $catId => $catDesc ) { # start new input field tag (category) $pview->addNewCategory( $catId ); $inp = array( '__tag' => 'input' ); $pview->resetSpanState(); # Determine the input's name and value. switch( $this->mType ) { case 'multipleChoice': $name = "q{$this->mQuestionId}p{$proposalId}s{$catId}"; $value = "s{$catId}"; break; case 'singleChoice': $name = "q{$this->mQuestionId}p{$proposalId}"; $value = "s{$catId}"; # category spans have sense only with single choice proposals $pview->renderSpan( $name, $value, $catDesc ); break; } # Determine if the input had to be checked. if ( $this->poll->mBeingCorrected && qp_Setup::$request->getVal( $name ) == $value ) { $inp[ 'checked' ] = 'checked'; } if ( $this->answerExists( $inputType, $proposalId, $catId ) !== false ) { $inp[ 'checked' ] = 'checked'; } if ( array_key_exists( 'checked', $inp ) ) { if ( $this->mSubType == 'unique' ) { if ( $this->poll->mBeingCorrected && !$this->isUniqueProposalCategoryId( $proposalId, $catId ) ) { $pview->prependErrorMessage( wfMsg( 'qp_error_non_unique_choice' ), 'NA' ); unset( $inp[ 'checked' ] ); qp_Renderer::addClass( $row[ $catId ], 'error' ); } } else { $pview->spanWasChecked( true ); } } if ( array_key_exists( 'checked', $inp ) ) { # add category to the list of user answers for current proposal (row) $this->mProposalCategoryId[ $proposalId ][] = $catId; $this->mProposalCategoryText[ $proposalId ][] = ''; } $pview->setCategorySpan(); if ( $this->mSubType == 'unique' ) { # unique (orderid,question,proposal,category) "coordinate" for javascript $inp['id'] = "uq{$this->poll->mOrderId}q{$this->mQuestionId}p{$proposalId}c{$catId}"; # If type='unique()' question has more proposals than categories, such question is impossible to complete if ( count( $this->mProposalText ) > count( $this->mCategories ) ) { # if there was no previous errors, hightlight the whole row if ( $this->getState() == '' ) { $pview->addCellsClass( 'error' ); } $pview->prependErrorMessage( wfMsg( 'qp_error_unique' ), 'error' ); } } $inp['class'] = 'check'; $inp['type'] = $inputType; $inp['name'] = $name; $inp['value'] = $value; $pview->setCat( $inp ); } # If the proposal text is empty, the question has a syntax error. if ( $pview->text !== null && trim( $pview->text ) == '' ) { $pview->setErrorMessage( wfMsg( 'qp_error_proposal_text_empty' ), 'error' ); $pview->addCellsClass( 'error' ); } if ( $inputType === 'radio' && $prop_attrs->catreq > 1 ) { # radio buttons row always require not more than one category, # otherwise the poll will be impossible to submit sucessfully. $prop_attrs->catreq = 1; } # If the proposal was submitted but unanswered if ( $this->poll->mBeingCorrected && $prop_attrs->hasMissingCategories( $answered_cats_count = $this->getAnsweredCatCount( $proposalId ), count( $this->mCategories ) ) ) { # if there was no previous errors, hightlight the whole row if ( $this->getState() == '' ) { $pview->addCellsClass( 'error' ); } # the proposal was submitted but has not enough categories answered $pview->prependErrorMessage( ($answered_cats_count > 0) ? wfMsg( 'qp_error_not_enough_categories_answered' ) : wfMsg( 'qp_error_no_answer' ) , 'NA' ); } if ( $pview->text !== null ) { $this->view->addProposal( $proposalId, $pview ); } } }