Skip to content
Snippets Groups Projects
Commit 7e08a798 authored by srosse's avatar srosse
Browse files

OO-2777: add warning if you replace a QTI 2.1 test

parent 48317537
No related branches found
No related tags found
No related merge requests found
/**
* <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.iq;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.zip.ZipOutputStream;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.media.FileMediaResource;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.nodes.QTICourseNode;
import org.olat.repository.RepositoryEntry;
/**
* This controller will make an archive of the current test entry results
* and propose some informations.
*
*
* Initial date: 24 mai 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class ConfirmChangeResourceController extends FormBasicController {
private FormLink downloadButton;
private final ICourse course;
private final File downloadArchiveFile;
private final QTICourseNode courseNode;
private final RepositoryEntry newTestEntry;
private final RepositoryEntry currentTestEntry;
private final int numOfAssessedIdentities;
public ConfirmChangeResourceController(UserRequest ureq, WindowControl wControl, ICourse course, QTICourseNode courseNode,
RepositoryEntry newTestEntry, RepositoryEntry currentTestEntry, int numOfAssessedIdentities) {
super(ureq, wControl, "confirm_change");
this.course = course;
this.courseNode = courseNode;
this.newTestEntry = newTestEntry;
this.currentTestEntry = currentTestEntry;
this.numOfAssessedIdentities = numOfAssessedIdentities;
downloadArchiveFile = prepareArchive(ureq);
initForm(ureq);
}
public RepositoryEntry getNewTestEntry() {
return newTestEntry;
}
public RepositoryEntry getCurrentTestEntry() {
return currentTestEntry;
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
if(formLayout instanceof FormLayoutContainer) {
FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
layoutCont.contextPut("infos1", translate("confirmation.change.warning.1", new String[]{ Integer.toString(numOfAssessedIdentities) }));
layoutCont.contextPut("infos2", translate("confirmation.change.warning.2"));
String[] archiveArgs = new String[] { downloadArchiveFile.getParentFile().getName(), downloadArchiveFile.getName() };
layoutCont.contextPut("infos3", translate("confirmation.change.warning.3", archiveArgs));
}
downloadButton = uifactory.addFormLink("download", downloadArchiveFile.getName(), null, formLayout, Link.LINK | Link.NONTRANSLATED);
downloadButton.setIconLeftCSS("o_icon o_icon_downloads");
uifactory.addFormCancelButton("cancel", formLayout, ureq, getWindowControl());
uifactory.addFormSubmitButton("ok", formLayout);
}
private File prepareArchive(UserRequest ureq) {
File exportDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), course.getCourseTitle());
String label = StringHelper.transformDisplayNameToFileSystemName(courseNode.getShortName())
+ "_" + Formatter.formatDatetimeWithMinutes(new Date()) + ".zip";
String urlEncodedLabel = StringHelper.urlEncodeUTF8(label);
File archiveFile = new File(exportDir, urlEncodedLabel);
try(OutputStream out= new FileOutputStream(archiveFile);
ZipOutputStream exportStream = new ZipOutputStream(out)) {
courseNode.archiveNodeData(getLocale(), course, null, exportStream, "UTF8");
return archiveFile;
} catch(Exception e) {
logError("", e);
return null;
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void formOK(UserRequest ureq) {
fireEvent(ureq, Event.DONE_EVENT);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(downloadButton == source) {
doDownload(ureq);
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void formCancelled(UserRequest ureq) {
fireEvent(ureq, Event.CANCELLED_EVENT);
}
private void doDownload(UserRequest ureq) {
ureq.getDispatchResult()
.setResultingMediaResource(new FileMediaResource(downloadArchiveFile, true));
}
}
\ No newline at end of file
......@@ -21,7 +21,9 @@ package org.olat.course.nodes.iq;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.Constants;
......@@ -52,6 +54,7 @@ import org.olat.course.nodes.AbstractAccessableCourseNode;
import org.olat.course.nodes.CourseNodeFactory;
import org.olat.course.nodes.IQSELFCourseNode;
import org.olat.course.nodes.IQSURVCourseNode;
import org.olat.course.nodes.QTICourseNode;
import org.olat.fileresource.types.ImsQTI21Resource;
import org.olat.ims.qti.QTIResult;
import org.olat.ims.qti.QTIResultManager;
......@@ -101,6 +104,7 @@ public class IQConfigurationController extends BasicController {
private IQEditReplaceWizard replaceWizard;
private AssessmentTestDisplayController previewQTI21Ctrl;
private ReferencableEntriesSearchController searchController;
private ConfirmChangeResourceController confirmChangeResourceCtrl;
private IQEditForm modOnyxConfigForm;
private IQ12EditForm mod12ConfigForm;
......@@ -287,20 +291,19 @@ public class IQConfigurationController extends BasicController {
@Override
public void event(UserRequest urequest, Controller source, Event event) {
if (source.equals(searchController)) {
if (source == searchController) {
if (event == ReferencableEntriesSearchController.EVENT_REPOSITORY_ENTRY_SELECTED) {
// repository search controller done
cmc.deactivate();
RepositoryEntry re = searchController.getSelectedEntry();
try {
boolean needManualCorrection = checkManualCorrectionNeeded(re);
doIQReference(urequest, re, needManualCorrection);
updateEditController(urequest, true);
} catch (Exception e) {
logError("", e);
showError("error.resource.corrupted");
}
doConfirmChangeTestAndSurvey(urequest, re);
}
} else if(source == confirmChangeResourceCtrl) {
if(event == Event.DONE_EVENT) {
RepositoryEntry newEntry = confirmChangeResourceCtrl.getNewTestEntry();
doChangeResource(urequest, newEntry);
}
cmc.deactivate();
} else if (source == replaceWizard) {
if(event == Event.CANCELLED_EVENT) {
cmc.deactivate();
......@@ -336,6 +339,58 @@ public class IQConfigurationController extends BasicController {
}
}
/**
* This check if there is some QTI 2.1 results for the current selected test.
*
* @param ureq
* @param newEntry
*/
private void doConfirmChangeTestAndSurvey(UserRequest ureq, RepositoryEntry newEntry) {
try {
RepositoryEntry currentEntry = courseNode.getReferencedRepositoryEntry();
RepositoryEntry courseEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
int numOfAssessedIdentities = 0;
if(currentEntry != null) {
List<AssessmentTestSession> assessmentTestSessions = qti21service.getAssessmentTestSessions(courseEntry, courseNode.getIdent(), currentEntry);
Set<Identity> assessedIdentities = new HashSet<>();
for(AssessmentTestSession assessmentTestSession:assessmentTestSessions) {
if(StringHelper.containsNonWhitespace(assessmentTestSession.getAnonymousIdentifier())) {
numOfAssessedIdentities++;
} else if(assessmentTestSession.getIdentity() != null) {
assessedIdentities.add(assessmentTestSession.getIdentity());
}
}
numOfAssessedIdentities += assessedIdentities.size();
}
if(numOfAssessedIdentities > 0) {
confirmChangeResourceCtrl = new ConfirmChangeResourceController(ureq, getWindowControl(),
course, (QTICourseNode)courseNode, newEntry, currentEntry, numOfAssessedIdentities);
listenTo(confirmChangeResourceCtrl);
cmc = new CloseableModalController(getWindowControl(), translate("close"), confirmChangeResourceCtrl.getInitialComponent());
listenTo(cmc);
cmc.activate();
} else {
doChangeResource(ureq, newEntry);
}
} catch (Exception e) {
logError("", e);
showError("error.resource.corrupted");
}
}
private void doChangeResource(UserRequest ureq, RepositoryEntry newEntry) {
try {
boolean needManualCorrection = checkManualCorrectionNeeded(newEntry);
doIQReference(ureq, newEntry, needManualCorrection);
updateEditController(ureq, true);
} catch (Exception e) {
logError("", e);
showError("error.resource.corrupted");
}
}
private void doPreview(UserRequest ureq) {
removeAsListenerAndDispose(previewLayoutCtr);
......
<div class="o_warning">
<strong>$r.infos1</strong><br>$infos2<br>$r.render("download")<br>$infos3
</div>
<div class="o_button_group">
$r.render("cancel")
$r.render("ok")
</div>
\ No newline at end of file
......@@ -22,6 +22,9 @@ command.preview=Vorschau anzeigen
command.showResults=Resultate anzeigen
comment.yourcomment=Kommentar vom Betreuer
condition.accessibility.title=Zugang
confirmation.change.warning.1=Dieser Test/Fragebogen wurde bereits von {0} Teilnehmer(n) gestartet und zum Teil auch beendet\!
confirmation.change.warning.2=Die Ergebnisse der beendeten Tests/Frageb\u00F6gen werden archiviert. Die archivierten Ergebnisse k\u00F6nnen Sie hier herunterladen\:
confirmation.change.warning.3=Eine Kopie dieser Ergebnis\u00FCbersicht finden Sie in Ihrem pers\u00F6nlichen Ordner unter\:<br><i>private/archive/{0}/{1}</i>.
correction.auto=Auto
correction.manual=Manuell
correction.mode=Korrektur
......
......@@ -22,6 +22,9 @@ command.preview=Show preview
command.showResults=Show results
comment.yourcomment=Comment from your tutor
condition.accessibility.title=Access
confirmation.change.warning.1=This test/questionnaire has already been launched by {0} participant(s) and finished in part\!
confirmation.change.warning.2=All results of tests/questionnaires already finished will be archived. The archived data can be downloaded here\:
confirmation.change.warning.3=A copy of this overview can be found in your personal folder:<br><i>private/archive/{0}/{1}</i>.
correction.auto=Auto
correction.manual=Manual
correction.mode=Correction
......
......@@ -22,6 +22,9 @@ command.preview=Afficher aper\u00E7u
command.showResults=Afficher r\u00E9sultat
comment.yourcomment=Commentaire du tuteur
condition.accessibility.title=Acc\u00E8s
confirmation.change.warning.1=Ce test/questionnaire a d\u00E9j\u00E0 \u00E9t\u00E9 lanc\u00E9 par {0} participant/s et partiellement termin\u00E9\!
confirmation.change.warning.2=Les r\u00E9sultats archiv\u00E9s peuvent \u00EAtre t\u00E9l\u00E9charg\u00E9s ici\:
confirmation.change.warning.3=Une copie de cette vue d'ensemble des r\u00E9sultats se trouve dans votre dossier personnel sous\:<br><i>private/archive/{0}/{1}</i>.
correction.auto=Automatique
correction.manual=Manuelle
correction.mode=Correction
......
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