Skip to content
Snippets Groups Projects
Commit eadb9a08 authored by uhensler's avatar uhensler
Browse files

OO-3303: Show survey in the course survey statistics

parent 0a3c987b
No related branches found
No related tags found
No related merge requests found
Showing
with 185 additions and 51 deletions
......@@ -54,7 +54,7 @@ import org.olat.course.run.userview.TreeFilter;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.course.statistic.StatisticType;
import org.olat.modules.ModuleConfiguration;
import org.olat.repository.RepositoryEntry;
......@@ -264,9 +264,9 @@ public interface CourseNode extends INode, ShortName {
* @return
*/
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, QTIType... type);
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type);
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, QTIType... type);
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type);
/**
* this method must generate a nodeevaluation and take care of (if any) child
......
......@@ -65,7 +65,7 @@ import org.olat.course.run.userview.TreeFilter;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.course.statistic.StatisticType;
import org.olat.modules.ModuleConfiguration;
/**
......@@ -82,7 +82,7 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
private Condition preConditionVisibility;
private Condition preConditionAccess;
protected transient StatusDescription[] oneClickStatusCache = null;
protected List<AdditionalCondition> additionalConditions = new ArrayList<AdditionalCondition>();
protected List<AdditionalCondition> additionalConditions = new ArrayList<>();
/**
* Generic course node constructor
......@@ -158,12 +158,12 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
@Override
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, QTIType... types) {
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type) {
return null;
}
@Override
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, QTIType... types) {
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type) {
return false;
}
......
......@@ -63,6 +63,7 @@ import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.course.statistic.StatisticType;
import org.olat.fileresource.types.ImsQTI21Resource;
import org.olat.ims.qti.QTIResultManager;
import org.olat.ims.qti.export.QTIExportFormatter;
......@@ -72,7 +73,6 @@ import org.olat.ims.qti.fileresource.SurveyFileResource;
import org.olat.ims.qti.process.AssessmentInstance;
import org.olat.ims.qti.statistics.QTIStatisticResourceResult;
import org.olat.ims.qti.statistics.QTIStatisticSearchParams;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.ims.qti21.QTI21DeliveryOptions;
import org.olat.ims.qti21.QTI21Service;
import org.olat.ims.qti21.model.QTI21StatisticSearchParams;
......@@ -169,8 +169,8 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
@Override
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, QTIType... types) {
if(!isQTITypeAllowed(types)) return null;
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type) {
if(!isStatisticTypeAllowed(type)) return null;
Long courseId = userCourseEnv.getCourseEnvironment().getCourseResourceableId();
OLATResourceable courseOres = OresHelper.createOLATResourceableInstance("CourseModule", courseId);
......@@ -193,25 +193,17 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
}
@Override
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, QTIType... types) {
return isQTITypeAllowed(types);
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type) {
return isStatisticTypeAllowed(type);
}
private boolean isQTITypeAllowed(QTIType... types) {
if(types == null) return true;
if(types.length == 0 || (types.length == 1 && types[0] == null)) return true;
for(QTIType type:types) {
if(QTIType.survey.equals(type)) {
return true;
}
private boolean isStatisticTypeAllowed(StatisticType type) {
if(StatisticType.SURVEY.equals(type)) {
return true;
}
return false;
}
/**
* @see org.olat.course.nodes.CourseNode#isConfigValid()
*/
@Override
public StatusDescription isConfigValid() {
/*
......
......@@ -77,6 +77,7 @@ import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.course.statistic.StatisticType;
import org.olat.fileresource.FileResourceManager;
import org.olat.fileresource.types.ImsQTI21Resource;
import org.olat.group.BusinessGroup;
......@@ -98,7 +99,6 @@ import org.olat.ims.qti.process.FilePersister;
import org.olat.ims.qti.resultexport.QTI12ResultsExportMediaResource;
import org.olat.ims.qti.statistics.QTIStatisticResourceResult;
import org.olat.ims.qti.statistics.QTIStatisticSearchParams;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.ims.qti21.AssessmentTestSession;
import org.olat.ims.qti21.QTI21DeliveryOptions;
import org.olat.ims.qti21.QTI21Service;
......@@ -313,8 +313,8 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
@Override
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, QTIType... types) {
if(!isQTITypeAllowed(types)) return null;
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type) {
if(!isStatisticTypeAllowed(type)) return null;
Long courseId = userCourseEnv.getCourseEnvironment().getCourseResourceableId();
OLATResourceable courseOres = OresHelper.createOLATResourceableInstance("CourseModule", courseId);
......@@ -337,18 +337,13 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
}
@Override
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, QTIType... types) {
return isQTITypeAllowed(types);
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type) {
return isStatisticTypeAllowed(type);
}
private boolean isQTITypeAllowed(QTIType... types) {
if(types == null) return true;
if(types.length == 0 || (types.length == 1 && types[0] == null)) return true;
for(QTIType type:types) {
if(QTIType.test.equals(type) || QTIType.onyx.equals(type) || QTIType.qtiworks.equals(type)) {
return true;
}
private boolean isStatisticTypeAllowed(StatisticType type) {
if(StatisticType.TEST.equals(type)) {
return true;
}
return false;
}
......
......@@ -42,9 +42,13 @@ import org.olat.course.export.CourseEnvironmentMapper;
import org.olat.course.nodes.survey.SurveyEditController;
import org.olat.course.nodes.survey.SurveyRunController;
import org.olat.course.nodes.survey.SurveyRunSecurityCallback;
import org.olat.course.nodes.survey.SurveyStatisticResourceResult;
import org.olat.course.run.navigation.NodeRunConstructionResult;
import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.course.statistic.StatisticType;
import org.olat.modules.ModuleConfiguration;
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormSurvey;
......@@ -67,7 +71,7 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
public static final String SURVEY_ICON = "o_survey_icon";
private static final String TYPE = "survey";
private static final String TYPE = "QTI_SURVEY";
public static final int CURRENT_VERSION = 1;
public static final String CONFIG_KEY_REPOSITORY_SOFTKEY = "repository.softkey";
......@@ -140,7 +144,31 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
public Controller createPreviewController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, NodeEvaluation ne) {
return createNodeRunConstructionResult(ureq, wControl, userCourseEnv, ne, null).getRunController();
}
@Override
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type) {
if (isStatisticAllowed(type)) {
RepositoryEntry ores = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
SurveyRunSecurityCallback secCallback = new SurveyRunSecurityCallback(getModuleConfiguration(), userCourseEnv);
Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity();
return new SurveyStatisticResourceResult(ores, getIdent(), identity, secCallback);
}
return null;
}
@Override
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type) {
return isStatisticAllowed(type);
}
private boolean isStatisticAllowed(StatisticType type) {
if(StatisticType.SURVEY.equals(type)) {
return true;
}
return false;
}
@SuppressWarnings("deprecation")
@Override
public StatusDescription[] isConfigValid(CourseEditorEnv cev) {
......@@ -230,3 +258,4 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
}
}
......@@ -119,7 +119,7 @@ public class SurveyRunSecurityCallback {
return participation != null && isExecutor() && !hasParticipated(participation);
}
boolean canViewReporting(EvaluationFormParticipation participation) {
public boolean canViewReporting(EvaluationFormParticipation participation) {
if (isReportViewer()) {
if (!isExecutor()) {
return true;
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.nodes.survey;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.stack.TooledStackedPanel;
import org.olat.core.gui.components.tree.TreeModel;
import org.olat.core.gui.components.tree.TreeNode;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.messages.SimpleMessageController;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.util.Util;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormParticipation;
import org.olat.modules.forms.EvaluationFormSurvey;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 30.05.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class SurveyStatisticResourceResult implements StatisticResourceResult {
private final OLATResourceable ores;
private final String subIdent;
private final Identity identity;
private final SurveyRunSecurityCallback secCallback;
@Autowired
private EvaluationFormManager evaluationFormManager;
public SurveyStatisticResourceResult(OLATResourceable ores, String subIdent, Identity identity,
SurveyRunSecurityCallback secCallback) {
this.ores = ores;
this.subIdent = subIdent;
this.identity = identity;
this.secCallback = secCallback;
CoreSpringFactory.autowireObject(this);
}
@Override
public TreeModel getSubTreeModel() {
return null;
}
@Override
public Controller getController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel,
TreeNode selectedNode) {
EvaluationFormSurvey survey = evaluationFormManager.loadSurvey(ores, subIdent);
EvaluationFormParticipation participation = evaluationFormManager.loadParticipationByExecutor(survey, identity);
if (secCallback.canViewReporting(participation)) {
return new SurveyReportingController(ureq, wControl, survey);
}
Translator translator = Util.createPackageTranslator(SurveyReportingController.class, ureq.getLocale());
String noAccess = translator.translate("report.noaccess");
return new SimpleMessageController(ureq, wControl, noAccess, "o_info");
}
}
......@@ -25,6 +25,7 @@ error.repo.entry.missing=Der Fragebogen, welchen Sie anzeigen m\u00F6chten, wurd
error.repo.entry.not.replaceable=Der Fragebogen kann nicht mehr ge\u00E4ndert werden.
pane.tab.accessibility=Zugang
pane.tab.config=Umfrage
report.noaccess=Sie haben keinen Zugang zu den Statistiken dieser Umfrage. Entweder fehlen ihnen die entsprechenden Berechtigungen oder Sie haben an der Umfrage noch nicht teilgenommen.
run.command.delete.data.all=Umfrage zur\u00fcksetzen
run.command.delete.data.all.confirmation.error=Best\u00E4tigen Sie bitte das L\u00f6schen.
run.command.delete.data.all.button=L\u00f6schen
......
......@@ -25,6 +25,7 @@ error.repo.entry.missing=This survey has been deleted in the meantime within the
error.repo.entry.not.replaceable=The questionnaire can not be replaced anymore.
pane.tab.accessibility=Access
pane.tab.config=Survey
report.noaccess=You do not have access to the statistics of this survey. Either you do not have the required rights or you do not have finished your participation.
run.command.delete.data.all=Reset survey
run.command.delete.data.all.confirmation.error=Please confirm the deletion of the responses.
run.command.delete.data.all.button=Delete
......
......@@ -113,12 +113,12 @@ import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.run.userview.UserCourseEnvironmentImpl;
import org.olat.course.statistic.StatisticCourseNodesController;
import org.olat.course.statistic.StatisticMainController;
import org.olat.course.statistic.StatisticType;
import org.olat.course.tree.CourseInternalLinkTreeModel;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupRef;
import org.olat.group.BusinessGroupService;
import org.olat.group.ui.edit.BusinessGroupModifiedEvent;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.instantMessaging.InstantMessagingModule;
import org.olat.instantMessaging.InstantMessagingService;
import org.olat.instantMessaging.OpenInstantMessageEvent;
......@@ -511,9 +511,9 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
new TreeVisitor(new Visitor() {
@Override
public void visit(INode node) {
if(((CourseNode)node).isStatisticNodeResultAvailable(uce, QTIType.test, QTIType.onyx)) {
if(((CourseNode)node).isStatisticNodeResultAvailable(uce, StatisticType.TEST)) {
testNodes.incrementAndGet();
} else if(((CourseNode)node).isStatisticNodeResultAvailable(uce, QTIType.survey)) {
} else if(((CourseNode)node).isStatisticNodeResultAvailable(uce, StatisticType.SURVEY)) {
surveyNodes.incrementAndGet();
}
}
......@@ -1570,7 +1570,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
private Activateable2 doAssessmentTestStatistics(UserRequest ureq) {
Activateable2 controller = null;
if(delayedClose == Delayed.assessmentTestStatistics || requestForClose(ureq)) {
controller = doAssessmentStatistics(ureq, "command.openteststatistic", "TestStatistics", testStatisticLink, QTIType.test, QTIType.onyx);
controller = doAssessmentStatistics(ureq, "command.openteststatistic", "TestStatistics", testStatisticLink, StatisticType.TEST);
} else {
delayedClose = Delayed.assessmentTestStatistics;
}
......@@ -1580,7 +1580,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
private Activateable2 doAssessmentSurveyStatistics(UserRequest ureq) {
Activateable2 controller = null;
if(delayedClose == Delayed.assessmentSurveyStatistics || requestForClose(ureq)) {
controller = doAssessmentStatistics(ureq, "command.opensurveystatistic", "SurveyStatistics", surveyStatisticLink, QTIType.survey);
controller = doAssessmentStatistics(ureq, "command.opensurveystatistic", "SurveyStatistics",
surveyStatisticLink, StatisticType.SURVEY);
} else {
delayedClose = Delayed.assessmentSurveyStatistics;
}
......@@ -1596,14 +1597,14 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
* @param types
* @return
*/
private Activateable2 doAssessmentStatistics(UserRequest ureq, String i18nCrumbKey, String typeName, Link tool, QTIType... types) {
private Activateable2 doAssessmentStatistics(UserRequest ureq, String i18nCrumbKey, String typeName, Link tool, StatisticType type) {
OLATResourceable ores = OresHelper.createOLATResourceableType(typeName);
ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
WindowControl swControl = addToHistory(ureq, ores, null);
if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) {
removeCustomCSS();
UserCourseEnvironmentImpl uce = getUserCourseEnvironment();
StatisticCourseNodesController ctrl = new StatisticCourseNodesController(ureq, swControl, toolbarPanel, reSecurity, uce, types);
StatisticCourseNodesController ctrl = new StatisticCourseNodesController(ureq, swControl, toolbarPanel, reSecurity, uce, type);
listenTo(ctrl);
statsToolCtr = pushController(ureq, translate(i18nCrumbKey), ctrl);
currentToolCtr = statsToolCtr;
......
......@@ -52,7 +52,6 @@ import org.olat.course.nodes.CourseNode;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.run.userview.UserCourseEnvironmentImpl;
import org.olat.group.BusinessGroup;
import org.olat.ims.qti.statistics.QTIType;
import org.olat.repository.RepositoryService;
import org.olat.repository.model.RepositoryEntrySecurity;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -68,17 +67,17 @@ public class StatisticCourseNodesController extends BasicController implements A
private final LayoutMain3ColsController layoutCtr;
private Controller currentCtrl;
private final QTIType[] types;
private final StatisticType type;
private final StatisticResourceOption options;
@Autowired
private RepositoryService repositoryService;
public StatisticCourseNodesController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel,
RepositoryEntrySecurity reSecurity, UserCourseEnvironment userCourseEnv, QTIType ... types) {
RepositoryEntrySecurity reSecurity, UserCourseEnvironment userCourseEnv, StatisticType type) {
super(ureq, wControl);
this.types = types;
this.type = type;
this.stackPanel = stackPanel;
options = new StatisticResourceOption();
......@@ -134,7 +133,7 @@ public class StatisticCourseNodesController extends BasicController implements A
@Override
public void visit(INode node) {
CourseNode courseNode = (CourseNode)node;
StatisticResourceResult result = courseNode.createStatisticNodeResult(ureq, getWindowControl(), userCourseEnv, options, types);
StatisticResourceResult result = courseNode.createStatisticNodeResult(ureq, getWindowControl(), userCourseEnv, options, type);
if(result != null) {
StatisticResourceNode courseNodeTreeNode = new StatisticResourceNode(courseNode, result);
rootTreeNode.addChild(courseNodeTreeNode);
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.statistic;
/**
*
* Initial date: 30.05.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public enum StatisticType {
TEST,
SURVEY
}
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