Skip to content
Snippets Groups Projects
Commit 396d5eb3 authored by srosse's avatar srosse
Browse files

OO-3455: allow feedback with only an image, a video or a math formula

parent 9f100be7
No related branches found
No related tags found
No related merge requests found
...@@ -19,9 +19,18 @@ ...@@ -19,9 +19,18 @@
*/ */
package org.olat.ims.qti21.model.xml; package org.olat.ims.qti21.model.xml;
import java.io.StringReader;
import java.util.List; import java.util.List;
import org.cyberneko.html.parsers.SAXParser;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.core.util.filter.FilterFactory;
import org.olat.ims.qti21.QTI21Constants; import org.olat.ims.qti21.QTI21Constants;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
import uk.ac.ed.ph.jqtiplus.node.expression.Expression; import uk.ac.ed.ph.jqtiplus.node.expression.Expression;
import uk.ac.ed.ph.jqtiplus.node.expression.general.BaseValue; import uk.ac.ed.ph.jqtiplus.node.expression.general.BaseValue;
...@@ -48,6 +57,8 @@ import uk.ac.ed.ph.jqtiplus.value.SingleValue; ...@@ -48,6 +57,8 @@ import uk.ac.ed.ph.jqtiplus.value.SingleValue;
*/ */
public class TestFeedbackBuilder { public class TestFeedbackBuilder {
private static final OLog log = Tracing.createLoggerFor(TestFeedbackBuilder.class);
private final TestFeedback testFeedback; private final TestFeedback testFeedback;
private final AssessmentTest assessmentTest; private final AssessmentTest assessmentTest;
...@@ -74,8 +85,7 @@ public class TestFeedbackBuilder { ...@@ -74,8 +85,7 @@ public class TestFeedbackBuilder {
} }
public OutcomeRule getResponseRule() { public OutcomeRule getResponseRule() {
OutcomeRule feedbackRule = findFeedbackRule(testFeedback.getOutcomeValue()); return findFeedbackRule(testFeedback.getOutcomeValue());
return feedbackRule;
} }
public boolean isPassedRule() { public boolean isPassedRule() {
...@@ -210,4 +220,51 @@ public class TestFeedbackBuilder { ...@@ -210,4 +220,51 @@ public class TestFeedbackBuilder {
} }
return false; return false;
} }
/**
*
* @param value The content of the feedback.
* @return
*/
public static boolean isEmpty(String value) {
if(!StringHelper.containsNonWhitespace(value)) {
return true;
}
if(StringHelper.containsNonWhitespace(FilterFactory.getHtmlTagsFilter().filter(value))) {
return false;
}
try {
SAXParser parser = new SAXParser();
HTMLHandler contentHandler = new HTMLHandler();
parser.setContentHandler(contentHandler);
parser.parse(new InputSource(new StringReader(value)));
return !contentHandler.hasRelevantTags();
} catch (Exception e) {
log.error("", e);
}
return true;
}
private static class HTMLHandler extends DefaultHandler {
private int count = 0;
public boolean hasRelevantTags() {
return count > 0;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
String elem = localName.toLowerCase();
if("img".equals(elem)) {
count++;
} else if("span".equals(elem) ) {
String cssClass = attributes.getValue("class");
if(cssClass != null && cssClass.contains("olatFlashMovieViewer")) {
count++;
}
}
}
}
} }
...@@ -43,8 +43,6 @@ import org.olat.core.gui.components.link.Link; ...@@ -43,8 +43,6 @@ import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.WindowControl;
import org.olat.core.util.CodeHelper; import org.olat.core.util.CodeHelper;
import org.olat.core.util.StringHelper;
import org.olat.core.util.filter.FilterFactory;
import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSContainer;
import org.olat.ims.qti21.model.xml.AssessmentItemBuilder; import org.olat.ims.qti21.model.xml.AssessmentItemBuilder;
import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder; import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder;
...@@ -52,6 +50,7 @@ import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder.ModalFeedbackType; ...@@ -52,6 +50,7 @@ import org.olat.ims.qti21.model.xml.ModalFeedbackBuilder.ModalFeedbackType;
import org.olat.ims.qti21.model.xml.ModalFeedbackCondition; import org.olat.ims.qti21.model.xml.ModalFeedbackCondition;
import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback; import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback;
import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback.Answer; import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback.Answer;
import org.olat.ims.qti21.model.xml.TestFeedbackBuilder;
import org.olat.ims.qti21.ui.ResourcesMapper; import org.olat.ims.qti21.ui.ResourcesMapper;
import org.olat.ims.qti21.ui.components.FlowFormItem; import org.olat.ims.qti21.ui.components.FlowFormItem;
import org.olat.ims.qti21.ui.editor.events.AssessmentItemEvent; import org.olat.ims.qti21.ui.editor.events.AssessmentItemEvent;
...@@ -287,13 +286,13 @@ public class FeedbacksEditorController extends FormBasicController implements Sy ...@@ -287,13 +286,13 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
@Override @Override
protected boolean validateFormLogic(UserRequest ureq) { protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true; boolean allOk = super.validateFormLogic(ureq);
for(RuledFeedbackForm additionalForm:additionalForms) { for(RuledFeedbackForm additionalForm:additionalForms) {
allOk &= additionalForm.validateFormLogic(); allOk &= additionalForm.validateFormLogic();
} }
return allOk & super.validateFormLogic(ureq); return allOk;
} }
@Override @Override
...@@ -353,8 +352,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy ...@@ -353,8 +352,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
} }
public boolean isEmpty() { public boolean isEmpty() {
String val = textEl.getValue(); return TestFeedbackBuilder.isEmpty(textEl.getValue());
return !StringHelper.containsNonWhitespace(FilterFactory.getHtmlTagsFilter().filter(val));
} }
public boolean isVisible() { public boolean isVisible() {
...@@ -368,7 +366,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy ...@@ -368,7 +366,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
public void commit() { public void commit() {
String title = titleEl.getValue(); String title = titleEl.getValue();
String text = textEl.getRawValue(); String text = textEl.getRawValue();
if(StringHelper.containsNonWhitespace(FilterFactory.getHtmlTagsFilter().filter(text))) { if(!TestFeedbackBuilder.isEmpty(text) ) {
feedbackBuilder = itemBuilder.getFeedbackBuilder(feedbackType); feedbackBuilder = itemBuilder.getFeedbackBuilder(feedbackType);
if(feedbackBuilder == null) { if(feedbackBuilder == null) {
feedbackBuilder = itemBuilder.createFeedbackBuilder(feedbackType); feedbackBuilder = itemBuilder.createFeedbackBuilder(feedbackType);
...@@ -496,7 +494,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy ...@@ -496,7 +494,7 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
feedbackConditions.add(condition.commit()); feedbackConditions.add(condition.commit());
} }
if(StringHelper.containsNonWhitespace(FilterFactory.getHtmlTagsFilter().filter(text)) && feedbackConditions.size() > 0) { if(!TestFeedbackBuilder.isEmpty(text) && !feedbackConditions.isEmpty()) {
if(feedbackBuilder == null) { if(feedbackBuilder == null) {
feedbackBuilder = itemBuilder.createFeedbackBuilder(feedbackType); feedbackBuilder = itemBuilder.createFeedbackBuilder(feedbackType);
} }
...@@ -735,13 +733,11 @@ public class FeedbacksEditorController extends FormBasicController implements Sy ...@@ -735,13 +733,11 @@ public class FeedbacksEditorController extends FormBasicController implements Sy
textValueEl.setVisible(!responseVar); textValueEl.setVisible(!responseVar);
dropDownValueEl.setVisible(responseVar); dropDownValueEl.setVisible(responseVar);
String[] answerKeys = new String[] {};
String[] answerValues = new String[] {};
if(itemBuilder instanceof ResponseIdentifierForFeedback) { if(itemBuilder instanceof ResponseIdentifierForFeedback) {
ResponseIdentifierForFeedback responseFeedback = (ResponseIdentifierForFeedback)itemBuilder; ResponseIdentifierForFeedback responseFeedback = (ResponseIdentifierForFeedback)itemBuilder;
List<Answer> answers = responseFeedback.getAnswers(); List<Answer> answers = responseFeedback.getAnswers();
answerKeys = new String[answers.size()]; String[] answerKeys = new String[answers.size()];
answerValues = new String[answers.size()]; String[] answerValues = new String[answers.size()];
for(int i=0; i<answers.size(); i++) { for(int i=0; i<answers.size(); i++) {
Answer answer = answers.get(i); Answer answer = answers.get(i);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment