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

OO-3303: Export surveys in course archive tool

parent 6dae0d60
No related branches found
No related tags found
No related merge requests found
Showing
with 114 additions and 22 deletions
......@@ -58,6 +58,7 @@ import org.olat.course.nodes.IQTESTCourseNode;
import org.olat.course.nodes.PFCourseNode;
import org.olat.course.nodes.ProjectBrokerCourseNode;
import org.olat.course.nodes.ScormCourseNode;
import org.olat.course.nodes.SurveyCourseNode;
import org.olat.course.nodes.TACourseNode;
import org.olat.course.nodes.WikiCourseNode;
......@@ -83,7 +84,7 @@ public class ArchiverMainController extends MainLayoutBasicController {
private static final String CMD_SCORM = "scorm";
private static final String CMD_CHECKLIST = "checklist";
private static final String CMD_PARTICIPANTFOLDER = "participantfolder";
private static final String CMD_SURVEY = "survey";
private IArchiverCallback archiverCallback;
......@@ -120,7 +121,7 @@ public class ArchiverMainController extends MainLayoutBasicController {
main.setContent(intro);
// Navigation menu
menuTree = new MenuTree("menuTree");
menuTree = new MenuTree("menuTree");
TreeModel tm = buildTreeModel(ureq);
menuTree.setTreeModel(tm);
menuTree.setSelectedNodeId(tm.getRootNode().getIdent());
......@@ -131,9 +132,6 @@ public class ArchiverMainController extends MainLayoutBasicController {
putInitialPanel(columnLayoutCtr.getInitialComponent());
}
/**
* @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
*/
@Override
public void event(UserRequest ureq, Component source, Event event) {
if (source == menuTree) {
......@@ -185,6 +183,13 @@ public class ArchiverMainController extends MainLayoutBasicController {
gtn.setAltText(translate("menu.qtiresults.alt"));
root.addChild(gtn);
}
if (archiverCallback.mayArchiveSurveys()) {
gtn = new GenericTreeNode();
gtn.setTitle(translate("menu.surveys"));
gtn.setUserObject(CMD_SURVEY);
gtn.setAltText(translate("menu.surveys.alt"));
root.addChild(gtn);
}
if (archiverCallback.mayArchiveQtiTestResults()) {
gtn = new GenericTreeNode();
gtn.setTitle(translate("menu.qtitestresults"));
......@@ -304,6 +309,9 @@ public class ArchiverMainController extends MainLayoutBasicController {
if (menuCommand.equals(CMD_QTISURVRESULTS)) {
contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new IQSURVCourseNode());
main.setContent(contentCtr.getInitialComponent());
} else if (menuCommand.equals(CMD_SURVEY)) {
contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new SurveyCourseNode());
main.setContent(contentCtr.getInitialComponent());
} else if (menuCommand.equals(CMD_QTITESTRESULTS)) {
contentCtr = new TestArchiveController(ureq, getWindowControl(), ores, new IQTESTCourseNode(), new IQSELFCourseNode());
main.setContent(contentCtr.getInitialComponent());
......@@ -346,9 +354,7 @@ public class ArchiverMainController extends MainLayoutBasicController {
}
}
/**
* @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
*/
@Override
protected void doDispose() {
// controllers disposed by BasicController:
columnLayoutCtr = null;
......
......@@ -91,4 +91,9 @@ public class FullAccessArchiverCallback implements IArchiverCallback {
public boolean mayArchiveProjectBroker() {
return true;
}
@Override
public boolean mayArchiveSurveys() {
return true;
}
}
......@@ -80,4 +80,6 @@ public interface IArchiverCallback {
* @return true if user has rights to archive project-broker data
*/
public boolean mayArchiveProjectBroker();
public boolean mayArchiveSurveys();
}
......@@ -77,6 +77,8 @@ menu.scoreaccounting=Kursresultate
menu.scoreaccounting.alt=Endresultate von Tests, Bewertungen und Aufgaben archivieren
menu.scorm=SCORM Resultate
menu.scorm.alt=SCORM Resultate
menu.surveys=Umfragen
menu.surveys.alt=Daten von Umfragen archivieren
menu.wikis=Wikis
menu.wikis.alt=Wikis archivieren
nodechoose.intro.config=Das Archiv enth\u00E4lt: alle Benutzer, alle Fragen, alle Items. \u00E4ndern Sie die Download-Konfiguration mit der Schaltfl\u00E4che oben.
......@@ -93,6 +95,7 @@ nodechoose.intro.scorm=W\u00E4hlen Sie im folgenden Dialog den SCORM Baustein au
nodechoose.intro.ta=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Aufgaben/L\u00F6sungen zu archivieren.
nodechoose.intro.wiki=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Wikis zu archivieren.
nodechoose.intro.checklist=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Checkliste zu archivieren.
nodechoose.intro.survey=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Umfrage zu archivieren.
overview.nonodes.checklist=Dieser Kurs enth\u00E4lt keine Checkliste.
overview.nonodes.iqtest=Dieser Kurs enth\u00E4lt keine Tests.
overview.nonodes.iqsurv=Dieser Kurs enth\u00E4lt keine Umfragen.
......@@ -111,6 +114,7 @@ select.group=Gruppe ausw\u00E4hlen
select.group.all=Alle Teilnehmer
select.group.desc=Sie k\u00F6nnen den Download auf einem bestimmte Gruppe beschr\u00E4nken, oder nicht.
showfile=Archivordner anzeigen
survey=Umfrage
ta=Aufgaben (alt)
table.action.download=Download
table.action.select=Ausw\u00E4hlen
......
......@@ -77,6 +77,8 @@ menu.scoreaccounting=Course results
menu.scoreaccounting.alt=Archive final results from tests, assessments and tasks
menu.scorm=SCORM results
menu.scorm.alt=SCORM results
menu.surveys=Surveys
menu.surveys.alt=Archive survey results
menu.wikis=Wikis
menu.wikis.alt=Archive Wikis
nodechoose.intro.config=The archive will contain: all users, all questions, all items. Change download configuration using button above.
......@@ -93,6 +95,7 @@ nodechoose.intro.scorm=In the following dialog please select the SCORM element t
nodechoose.intro.ta=Select a course element in order to archive its tasks/solutions.
nodechoose.intro.wiki=Select a course element to archive its Wiki.
nodechoose.intro.checklist=Select a course element to archive its checklists.
nodechoose.intro.survey=Select a course element to archive its survey results.
overview.nonodes.iqtest=This course does not contain any tests.
overview.nonodes.iqsurv=This course does not contain any surveys.
overview.nonodes.checklist=This course does not contain any checklists.
......@@ -111,6 +114,7 @@ select.group=Select group
select.group.all=All participants
select.group.desc=You can limit the download to a particular group if you wish.
showfile=Show archive folder
survey=Survey
ta=Tasks/solutions
table.action.download=Download
table.action.select=Select
......
......@@ -19,9 +19,13 @@
*/
package org.olat.course.nodes;
import static org.olat.modules.forms.handler.EvaluationFormResource.FORM_XML_FILE;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.zip.ZipOutputStream;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
......@@ -31,8 +35,11 @@ import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.tabbable.TabbableController;
import org.olat.core.id.Identity;
import org.olat.core.id.Organisation;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.course.ICourse;
import org.olat.course.condition.ConditionEditController;
import org.olat.course.editor.CourseEditorEnv;
......@@ -49,10 +56,19 @@ 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.modules.ModuleConfiguration;
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormSession;
import org.olat.modules.forms.EvaluationFormSessionStatus;
import org.olat.modules.forms.EvaluationFormSurvey;
import org.olat.modules.forms.handler.EvaluationFormResource;
import org.olat.modules.forms.model.xml.Form;
import org.olat.modules.forms.model.xml.FormXStream;
import org.olat.modules.forms.ui.EvaluationFormExcelExport;
import org.olat.modules.forms.ui.LegendNameGenerator;
import org.olat.modules.forms.ui.ReportHelper;
import org.olat.modules.forms.ui.SessionInformationLegendNameGenerator;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryImportExport;
import org.olat.repository.RepositoryManager;
......@@ -66,6 +82,8 @@ import org.olat.repository.handlers.RepositoryHandlerFactory;
*
*/
public class SurveyCourseNode extends AbstractAccessableCourseNode {
private static final OLog log = Tracing.createLoggerFor(SurveyCourseNode.class);
private static final long serialVersionUID = 905046067514602922L;
......@@ -238,6 +256,35 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
}
}
}
@Override
public boolean archiveNodeData(Locale locale, ICourse course, ArchiveOptions options, ZipOutputStream exportStream,
String charset) {
RepositoryEntry ores = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
EvaluationFormManager evaluationFormManager = CoreSpringFactory.getImpl(EvaluationFormManager.class);
EvaluationFormSurvey survey = evaluationFormManager.loadSurvey(ores, getIdent());
List<EvaluationFormSession> sessions = evaluationFormManager.loadSessionsBySurvey(survey,
EvaluationFormSessionStatus.done);
File repositoryDir = new File(
FileResourceManager.getInstance().getFileResourceRoot(survey.getFormEntry().getOlatResource()),
FileResourceManager.ZIPDIR);
File formFile = new File(repositoryDir, FORM_XML_FILE);
Form form = (Form) XStreamHelper.readObject(FormXStream.getXStream(), formFile);
LegendNameGenerator legendNameGenerator = new SessionInformationLegendNameGenerator(sessions);
ReportHelper reportHelper = ReportHelper.builder(locale).withLegendNameGenrator(legendNameGenerator).build();
EvaluationFormExcelExport evaluationFormExport = new EvaluationFormExcelExport(form, sessions, reportHelper,
getShortName());
try {
evaluationFormExport.export(exportStream);
} catch (IOException e) {
log.error("", e);
return false;
}
return true;
}
public static RepositoryEntry getEvaluationForm(ModuleConfiguration config) {
if (config == null) return null;
......@@ -256,6 +303,5 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
public static void removeEvaluationFormReference(ModuleConfiguration moduleConfig) {
moduleConfig.remove(CONFIG_KEY_REPOSITORY_SOFTKEY);
}
}
......@@ -353,4 +353,5 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager {
return statistic;
}
}
......@@ -110,6 +110,7 @@ public class EvaluationFormResponseDAO {
sb.append("select response from evaluationformresponse as response");
sb.append(" inner join fetch response.session as session");
sb.append(" left outer join fetch session.participation as participation");
sb.append(" left outer join fetch participation.executor as executor");
sb.append(" where session.key in (:sessionKeys)");
return dbInstance.getCurrentEntityManager()
......@@ -125,6 +126,7 @@ public class EvaluationFormResponseDAO {
sb.append("select response from evaluationformresponse as response");
sb.append(" inner join fetch response.session as session");
sb.append(" left outer join fetch session.participation as participation");
sb.append(" left outer join fetch participation.executor as executor");
sb.append(" inner join session.survey as survey");
sb.append(" where survey.key=:surveyKey");
......
......@@ -27,6 +27,8 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.olat.core.CoreSpringFactory;
import org.olat.core.logging.OLog;
......@@ -64,35 +66,55 @@ import org.springframework.beans.factory.annotation.Autowired;
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class EvaluationFormExport extends OpenXMLWorkbookResource {
public class EvaluationFormExcelExport {
private static final OLog log = Tracing.createLoggerFor(EvaluationFormExport.class);
private static final OLog log = Tracing.createLoggerFor(EvaluationFormExcelExport.class);
private final String fileName;
private final Form form;
private final List<EvaluationFormSession> sessions;
private List<EvaluationFormSession> sessions;
private final ReportHelper reportHelper;
private final EvaluationFormResponses responses;
@Autowired
private EvaluationFormManager evaluationFormManager;
public EvaluationFormExport(Form form, List<EvaluationFormSession> sessions, ReportHelper reportHelper, String surveyName) {
super(label(surveyName));
public EvaluationFormExcelExport(Form form, List<EvaluationFormSession> sessions, ReportHelper reportHelper, String surveyName) {
this.fileName = getFileName(surveyName);
this.form = form;
this.sessions = sessions;
this.reportHelper = reportHelper;
CoreSpringFactory.autowireObject(this);
responses = evaluationFormManager.loadResponsesBySessions(sessions);
}
private static final String label(String surveyName) {
return StringHelper.transformDisplayNameToFileSystemName(surveyName)
+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()))
+ ".xlsx";
private String getFileName(String surveyName) {
return new StringBuilder()
.append(StringHelper.transformDisplayNameToFileSystemName(surveyName))
.append("_")
.append(Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis())))
.append(".xlsx")
.toString();
}
public OpenXMLWorkbookResource createMediaResource() {
// refresh to avoid lazy instantiation exception
sessions = evaluationFormManager.loadSessionsByKey(sessions, 0, -1);
return new OpenXMLWorkbookResource(fileName) {
@Override
protected void generate(OutputStream out) {
createWorkbook(out);
}
};
}
public void export(ZipOutputStream out) throws IOException {
out.putNextEntry(new ZipEntry(fileName));
createWorkbook(out);
}
@Override
protected void generate(OutputStream out) {
private void createWorkbook(OutputStream out) {
try(OpenXMLWorkbook workbook = new OpenXMLWorkbook(out, 1)) {
OpenXMLWorksheet exportSheet = workbook.nextWorksheet();
addHeader(exportSheet);
......
......@@ -131,8 +131,8 @@ public class EvaluationFormReportsController extends BasicController {
private void doExport(UserRequest ureq) {
String surveyName = "survey";
EvaluationFormExport export = new EvaluationFormExport(form, sessions, reportHelper, surveyName);
ureq.getDispatchResult().setResultingMediaResource(export);
EvaluationFormExcelExport export = new EvaluationFormExcelExport(form, sessions, reportHelper, surveyName);
ureq.getDispatchResult().setResultingMediaResource(export.createMediaResource());
}
}
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