Skip to content
Snippets Groups Projects
Commit 02d595e8 authored by srosse's avatar srosse
Browse files

Merge remote-tracking branch 'origin/OpenOLAT_15.2' into OpenOLAT_15.3

parents ddaf4c7f db1b32f6
No related branches found
No related tags found
No related merge requests found
...@@ -369,8 +369,8 @@ public class ScormRunController extends BasicController implements ScormAPICallb ...@@ -369,8 +369,8 @@ public class ScormRunController extends BasicController implements ScormAPICallb
@Override @Override
public void lmsFinish(String olatSahsId, Properties scoreProp, Properties lessonStatusProp) { public void lmsFinish(String olatSahsId, Properties scoreProp, Properties lessonStatusProp) {
doStartPage(null);
if (config.getBooleanSafe(ScormEditController.CONFIG_CLOSE_ON_FINISH, false)) { if (config.getBooleanSafe(ScormEditController.CONFIG_CLOSE_ON_FINISH, false)) {
doStartPage(null);
scormDispC.close(); scormDispC.close();
} }
} }
......
...@@ -88,8 +88,8 @@ public class OLATApiAdapter implements ch.ethz.pfplms.scorm.api.ApiAdapterInterf ...@@ -88,8 +88,8 @@ public class OLATApiAdapter implements ch.ethz.pfplms.scorm.api.ApiAdapterInterf
private Properties scoresProp; // keys: sahsId; values = raw score of an sco private Properties scoresProp; // keys: sahsId; values = raw score of an sco
private Properties lessonStatusProp; private Properties lessonStatusProp;
private final String SCORE_IDENT = "cmi.core.score.raw"; private static final String SCORE_IDENT = "cmi.core.score.raw";
private final String LESSON_STATUS_IDENT = "cmi.core.lesson_status"; private static final String LESSON_STATUS_IDENT = "cmi.core.lesson_status";
private File scorePropsFile; private File scorePropsFile;
private File lessonStatusPropsFile; private File lessonStatusPropsFile;
...@@ -162,7 +162,7 @@ public class OLATApiAdapter implements ch.ethz.pfplms.scorm.api.ApiAdapterInterf ...@@ -162,7 +162,7 @@ public class OLATApiAdapter implements ch.ethz.pfplms.scorm.api.ApiAdapterInterf
private final void say (String s) { private final void say (String s) {
log.debug("core: "+s); log.debug("core: {}", s);
} }
......
...@@ -36,12 +36,16 @@ import java.util.Properties; ...@@ -36,12 +36,16 @@ import java.util.Properties;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurity;
import org.olat.core.CoreSpringFactory; import org.olat.core.CoreSpringFactory;
import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.dispatcher.mapper.Mapper;
import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.MediaResource;
import org.olat.core.gui.media.ServletUtil;
import org.olat.core.gui.media.StringMediaResource; import org.olat.core.gui.media.StringMediaResource;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.core.id.IdentityEnvironment; import org.olat.core.id.IdentityEnvironment;
...@@ -322,43 +326,90 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable { ...@@ -322,43 +326,90 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
String apiCallParamTwo = request.getParameter("apiCallParamTwo"); String apiCallParamTwo = request.getParameter("apiCallParamTwo");
if(log.isDebugEnabled()) { if(log.isDebugEnabled()) {
log.debug("scorm api request by user:"+ identity.getName() +": " + apiCall + "('" + apiCallParamOne + "' , '" + apiCallParamTwo + "')"); log.debug("scorm api request by user: {}: {} ('{}' , '{}')", identity.getName(), apiCall, apiCallParamOne, apiCallParamTwo);
} }
StringMediaResource smr = new StringMediaResource();
smr.setContentType("text/html");
smr.setEncoding("utf-8");
if (apiCall != null && apiCall.equals("initcall")) { if (apiCall != null && apiCall.equals("initcall")) {
//used for Mozilla / firefox only to get more time for fireing the onunload stuff triggered by overwriting the content. //used for Mozilla / firefox only to get more time for fireing the onunload stuff triggered by overwriting the content.
smr.setData("<html><body></body></html>"); log.info("Init call");
return smr; return createInitResource(request);
} }
String returnValue = "";
if (apiCall != null) { if (apiCall != null) {
if (apiCall.equals(LMS_INITIALIZE)) { String returnValue = apiCall(apiCall, apiCallParamOne, apiCallParamTwo);
returnValue = scormAdapter.LMSInitialize(apiCallParamOne); return createResource(returnValue, request);
} else if (apiCall.equals(LMS_GETVALUE)) { } else if(relPath.contains("batch")) {
returnValue = scormAdapter.LMSGetValue(apiCallParamOne); try {
} else if (apiCall.equals(LMS_SETVALUE)) { String batch = IOUtils.toString(request.getReader());
returnValue = scormAdapter.LMSSetValue(apiCallParamOne, apiCallParamTwo); JSONArray batchArray = new JSONArray(batch);
} else if (apiCall.equals(LMS_COMMIT)) { for(int i=0; i<batchArray.length(); i++) {
returnValue = scormAdapter.LMSCommit(apiCallParamOne); JSONObject obj = batchArray.getJSONObject(i);
} else if (apiCall.equals(LMS_FINISH)) { apiCall = obj.getString("apiCall");
returnValue = scormAdapter.LMSFinish(apiCallParamOne); apiCallParamOne = obj.getString("param1");
} else if (apiCall.equals(LMS_GETLASTERROR)) { apiCallParamTwo = obj.getString("param2");
returnValue = scormAdapter.LMSGetLastError(); apiCall(apiCall, apiCallParamOne, apiCallParamTwo);
} else if (apiCall.equals(LMS_GETDIAGNOSTIC)) { }
returnValue = scormAdapter.LMSGetDiagnostic(apiCallParamOne); } catch (IOException e) {
} else if (apiCall.equals(LMS_GETERRORSTRING)) { log.error("", e);
returnValue = scormAdapter.LMSGetErrorString(apiCallParamOne);
} }
smr.setData("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><p>"
+ returnValue + "</p></body></html>");
return smr;
} }
smr.setData(""); return createResource("", request);
}
private String apiCall(String apiCall, String apiCallParamOne, String apiCallParamTwo) {
String returnValue = "";
if (apiCall.equals(LMS_INITIALIZE)) {
returnValue = scormAdapter.LMSInitialize(apiCallParamOne);
} else if (apiCall.equals(LMS_GETVALUE)) {
returnValue = scormAdapter.LMSGetValue(apiCallParamOne);
} else if (apiCall.equals(LMS_SETVALUE)) {
returnValue = scormAdapter.LMSSetValue(apiCallParamOne, apiCallParamTwo);
} else if (apiCall.equals(LMS_COMMIT)) {
returnValue = scormAdapter.LMSCommit(apiCallParamOne);
} else if (apiCall.equals(LMS_FINISH)) {
returnValue = scormAdapter.LMSFinish(apiCallParamOne);
} else if (apiCall.equals(LMS_GETLASTERROR)) {
returnValue = scormAdapter.LMSGetLastError();
} else if (apiCall.equals(LMS_GETDIAGNOSTIC)) {
returnValue = scormAdapter.LMSGetDiagnostic(apiCallParamOne);
} else if (apiCall.equals(LMS_GETERRORSTRING)) {
returnValue = scormAdapter.LMSGetErrorString(apiCallParamOne);
}
return returnValue;
}
private MediaResource createInitResource(HttpServletRequest request) {
MediaResource resource;
boolean acceptJson = ServletUtil.acceptJson(request);
if(acceptJson && request == null) {
resource = createHTMLResource("");
} else {
resource = createHTMLResource("<html><body></body></html>");
}
return resource;
}
private MediaResource createResource(String returnValue, HttpServletRequest request) {
MediaResource resource;
boolean acceptJson = ServletUtil.acceptJson(request);
if(acceptJson && request == null) {
resource = createHTMLResource("");
} else if(StringHelper.containsNonWhitespace(returnValue)) {
String data = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><p>" + returnValue + "</p></body></html>";
resource = createHTMLResource(data);
} else {
resource = createHTMLResource("");
}
return resource;
}
private StringMediaResource createHTMLResource(String data) {
StringMediaResource smr = new StringMediaResource();
smr.setContentType("text/html");
smr.setEncoding("utf-8");
smr.setData(data);
return smr; return smr;
} }
} }
\ No newline at end of file
...@@ -29,6 +29,7 @@ import java.io.File; ...@@ -29,6 +29,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import org.olat.core.commons.fullWebApp.LayoutMain3ColsBackController; import org.olat.core.commons.fullWebApp.LayoutMain3ColsBackController;
import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
...@@ -73,7 +74,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -73,7 +74,7 @@ import org.springframework.beans.factory.annotation.Autowired;
* the sco api calls to the scorm RTE backend. It provides also an navigation to * the sco api calls to the scorm RTE backend. It provides also an navigation to
* navigate in the tree with "pre" "next" buttons. * navigate in the tree with "pre" "next" buttons.
*/ */
public class ScormAPIandDisplayController extends MainLayoutBasicController implements ConfigurationChangedListener { public class ScormAPIandDisplayController extends MainLayoutBasicController implements ConfigurationChangedListener, ScormAPICallback {
protected static final String LMS_INITIALIZE = "LMSInitialize"; protected static final String LMS_INITIALIZE = "LMSInitialize";
protected static final String LMS_GETVALUE = "LMSGetValue"; protected static final String LMS_GETVALUE = "LMSGetValue";
...@@ -136,6 +137,7 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController impl ...@@ -136,6 +137,7 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController impl
try { try {
scormAdapter = new OLATApiAdapter(); scormAdapter = new OLATApiAdapter();
scormAdapter.addAPIListener(apiCallback); scormAdapter.addAPIListener(apiCallback);
scormAdapter.addAPIListener(this);
String fullname = UserManager.getInstance().getUserDisplayName(getIdentity()); String fullname = UserManager.getInstance().getUserDisplayName(getIdentity());
String scormResourceIdStr = scormResourceId == null ? null : scormResourceId.toString(); String scormResourceIdStr = scormResourceId == null ? null : scormResourceId.toString();
scormAdapter.init(cpRoot, scormResourceIdStr, courseIdNodeId, FolderConfig.getCanonicalRoot(), username, fullname, lesson_mode, credit_mode, hashCode()); scormAdapter.init(cpRoot, scormResourceIdStr, courseIdNodeId, FolderConfig.getCanonicalRoot(), username, fullname, lesson_mode, credit_mode, hashCode());
...@@ -322,6 +324,16 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController impl ...@@ -322,6 +324,16 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController impl
} }
} }
@Override
public void lmsCommit(String olatSahsId, Properties scoScores, Properties scoLessonStatus) {
//
}
@Override
public void lmsFinish(String olatSahsId, Properties scoProps, Properties scoLessonStatus) {
myContent.setDirty(false);
}
@Override @Override
protected void event(UserRequest ureq, Controller source, Event event) { protected void event(UserRequest ureq, Controller source, Event event) {
if(source == columnLayoutCtr) { if(source == columnLayoutCtr) {
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
## method to send a ping to the framework to draw itself after finish ## method to send a ping to the framework to draw itself after finish
function pingAfterFinish() { function pingAfterFinish() {
window.suppressOlatOnUnloadOnce = true; window.suppressOlatOnUnloadOnce = true;
$r.javaScriptCommand('ping'); try {
$r.javaScriptCommand('ping');
} catch(e) {
if(window.console) console.log(e);
}
} }
</script> </script>
<script> <script>
......
...@@ -16,137 +16,43 @@ var API = window; ...@@ -16,137 +16,43 @@ var API = window;
* right now only used for moz, as ie has some problems with state handler * right now only used for moz, as ie has some problems with state handler
* room for improvement by makeing it into one function that works for both * room for improvement by makeing it into one function that works for both
*/ */
function scormApiRequest(remoteUrl) function scormApiRequest(remoteUrl) {
{ this.remoteOLATurl = remoteUrl;
this.remoteOLATurl = remoteUrl; this.reqCount = 0;
this.isMozilla = false;
this.httpReq=false;
this.reqCount = 0;
this.sendSyncSingle = asSendSyncSingle;
if (window.XMLHttpRequest)
{
this.httpReq = new XMLHttpRequest();
this.isMozilla = true;
if (debug) dump("func:scormApiRequest :is Mozilla\n");
}
// code for IE
else if (window.ActiveXObject)
{
try {
this.httpReq = new ActiveXObject("Msxml2.XMLHTTP");
if (debug) dump("func:scormApiRequest :is new IE \n");
} catch (e) {
try {
this.httpReq = new ActiveXObject("Microsoft.XMLHTTP");
if (debug) dump("func:scormApiRequest :is old IE \n");
} catch (E) {
this.httpReq = false;
}
}
}
}
function asSendSyncSingle(apiCall, param1, param2) {
// Sync - wait until data arrives
//IE does not like this function, what's it for?
//httpReq.multipart = false;
// Mozilla/Firefox bug 246518 workaround
// a new XMLHttpRequest object if needed
try {
this.httpReq.onload = showReq;
this.httpReq.onreadystatechange = showReq;
this.httpReq.open('POST', this.remoteOLATurl, false );
} catch (e) {
this.httpReq = new XMLHttpRequest();
this.httpReq.onload = showReq;
this.httpReq.onreadystatechange = showReq;
this.httpReq.open('POST', this.remoteOLATurl, false );
}
this.httpReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
this.httpReq.send('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2));
if(this.isMozilla)
{
if (debug) dump("func:asSencSingle: post successfull, calling showReq\n");
//add event listener geht auch! ev. besser?
//httpReq.addEventListener("load", showReq, false)
//this.httpReq.onload = showReq;
//this.httpReq.onreadystatechange = showReq;
} else {
if (debug) dump("func:asSencSingle: post successfull by this.httpReq, calling showReq\n");
//this.httpReq.onload = showReq;
//this.httpReq.onreadystatechange = showReq;
}
//httpReq.send(null);
}
function showReq( event ) {
if (debug) dump("func:showReq: inside func.: event type: " +event.type+"\n");
// ready state 4 means document loaded
//if ( event.target.readyState == 4 )
if ( this.readyState == 4 )
{
bMsg = document.getElementById( 'apiReturnHandler' );
//bMsg.innerHTML = event.target.responseText;
bMsg.innerHTML = this.responseText;
bMsg = null;
if (debug) dump("func:showReq: "+this.responseText+"\n");
} else { if (debug) dump( 'an error occured! Wrong readyState: ' + event.target.readyState +"\n"); }
} }
/*************************************/ /*************************************/
// global flag
var isIE = false;
// global request and XML document objects
var scormRTEresponse;
// retrieve XML document (reusable generic function); // retrieve XML document (reusable generic function);
function loadHTMLDoc(url,apiCall, param1, param2) { function loadHTMLDoc(url, async, apiCall, param1, param2) {
var req; var scormResponse;
// inner callback method to handle onreadystatechange event of req object var req = new XMLHttpRequest();
var processReqChange = function (event){ req.onreadystatechange = function (event) {
// only if req shows "loaded" // only if req shows "loaded"
if (req.readyState == 4) { if (req.readyState == 4) {
// only if "OK" // only if "OK"
if (req.status == 200) { if (req.status == 200) {
rteResponseText = req.responseText; scormResponse = loadHTMLDocExtractResponse(req.responseText);
scormRTEresponse = rteResponseText.substring(rteResponseText.indexOf("<p>")+3,rteResponseText.indexOf("</p>")); if (debug) dump(scormResponse);
if (debug) dump(scormRTEresponse); } else if (debug) {
} else { if (debug) dump("There was a problem retrieving the XMLHttpRequest data:\n"+ req.statusText+"\n"); } dump("There was a problem retrieving the XMLHttpRequest data:\n"+ req.statusText+"\n");
}
} }
}; };
// branch for native XMLHttpRequest object req.open("POST", url, async);
if (window.XMLHttpRequest) { req.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
req = new XMLHttpRequest(); req.send('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2));
req.onreadystatechange = processReqChange; if (debug) dump('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2));
//req.open("GET", url+'?apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ param2, false); return scormResponse;
req.open("POST", url, false) }
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
req.send('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2)); function loadHTMLDocExtractResponse(responseText) {
if (debug) dump('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2)); if("<html><body></body></html>" == responseText) {
// branch for IE/Windows ActiveX version return "";// initial call
} else if (window.ActiveXObject) { }
isIE = true; return responseText.substring(responseText.indexOf("<p>") + 3, responseText.indexOf("</p>"));
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
//req.open("GET", url+'?apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ param2 + '&rnd='+increment(), false);
//req.send();
req.open("POST", url, false);
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
req.send('apiCall='+ apiCall + '&apiCallParamOne='+ param1 + '&apiCallParamTwo='+ encodeURIComponent(param2));
}
}
// Help GC
req = null;
} }
/***************************************************************** /*****************************************************************
...@@ -164,20 +70,15 @@ function increment(){ ...@@ -164,20 +70,15 @@ function increment(){
* over a synchronous XmlHttpRequest. * over a synchronous XmlHttpRequest.
* Code uses different ways for moz and ie. * Code uses different ways for moz and ie.
*******************************************************************/ *******************************************************************/
function passApiCall(apiCall, param1, param2){
if(window.ActiveXObject || (navigator.userAgent.indexOf("Safari") != -1)){ function passApiCall(apiCall, param1, param2) {
loadHTMLDoc(olatCommandUri,apiCall,param1,param2); try {
return scormRTEresponse; return loadHTMLDoc(olatCommandUri, false, apiCall, param1, param2);
}else if(window.XMLHttpRequest && (navigator.userAgent.indexOf("Mozilla") != -1)){ } catch(e) {
jsHttpRequest.sendSyncSingle(apiCall,param1, param2); if(window.console) console.log(e);
var responseHTML = document.getElementById( 'apiReturnHandler' ).innerHTML;
return responseHTML.substring(responseHTML.indexOf("<p>")+3,responseHTML.indexOf("</p>"));
}else{
if (debug) dump("Browser does not support the needed XmlHttpRequest\n");
} }
} }
/** /**
* triggers the onunload stuff often used in scorm content to finish an sco by * triggers the onunload stuff often used in scorm content to finish an sco by
* opening the iframe document for writing (IE) or replacing the content doc (Mozilla). * opening the iframe document for writing (IE) or replacing the content doc (Mozilla).
...@@ -185,34 +86,27 @@ function passApiCall(apiCall, param1, param2){ ...@@ -185,34 +86,27 @@ function passApiCall(apiCall, param1, param2){
function olatonunload(){ function olatonunload(){
if (debug) dump("func:olatonunload: is called\n"); if (debug) dump("func:olatonunload: is called\n");
if(window.frameId && document.getElementById(frameId) && this.frames[frameId]){ if(window.frameId && document.getElementById(frameId) && this.frames[frameId]){
if(window.ActiveXObject){ // Mozilla and others
//on IE by opening the document, the onunload event gets triggered var iframeDoc = document.getElementById(frameId).contentDocument;
var iframeDoc = this.frames[frameId].document; iframeDoc.location.replace("about:blank");
iframeDoc.open(); iframeDoc = null;
iframeDoc.write("<html><body></body></html>");
iframeDoc.close(); var delayReq = new XMLHttpRequest();
iframeDoc = null; //"false" waits until the result arrived;
} else { delayReq.open('GET', olatCommandUri, false );
// Mozilla and others delayReq.send(null);
var iframeDoc = document.getElementById(frameId).contentDocument;
iframeDoc.location.replace("about:blank");
iframeDoc = null;
//delay(200);
//if((new Date().getTime() - lastRequest) > 60000) alert("Current SCO will be finished before initializing next SCO or terminating! Press OK to proceed.");
var delayReq = new XMLHttpRequest();
//"false" waits until the result arrived;
delayReq.open('GET', olatCommandUri, false );
delayReq.send(null);
}
} }
return true; return true;
} }
function delay(gap){
var then,now; then=new Date().getTime(); var openolatScormUnloadQueue = new Array();
now=then;
while((now-then)<gap) function queueCall(apiCall, param1, param2) {
{now=new Date().getTime();} var entry = new Object();
entry.apiCall = apiCall;
entry.param1 = param1;
entry.param2 = param2;
openolatScormUnloadQueue.push(entry);
} }
/****************************************************************** /******************************************************************
...@@ -224,7 +118,14 @@ function LMSInitialize (s) { ...@@ -224,7 +118,14 @@ function LMSInitialize (s) {
return passApiCall('LMSInitialize',s,''); return passApiCall('LMSInitialize',s,'');
} }
function LMSFinish (s) { function LMSFinish (s) {
var finishedResult = passApiCall('LMSFinish',s,''); var finishedResult = passApiCall('LMSFinish', s, '');
if(typeof val === "undefined") {
// Communication problem, try to send all queued data as beacon
queueCall('LMSFinish', s, '');
var data = JSON.stringify(openolatScormUnloadQueue);
openolatScormUnloadQueue = new Array();
navigator.sendBeacon(olatCommandUri + "/batch/data/", data);
}
// Immediately close module, ping OpenOlat main window to take over control // Immediately close module, ping OpenOlat main window to take over control
setTimeout(function(){ setTimeout(function(){
try { try {
...@@ -236,20 +137,38 @@ function LMSFinish (s) { ...@@ -236,20 +137,38 @@ function LMSFinish (s) {
return finishedResult; return finishedResult;
} }
function LMSSetValue (l, r) { function LMSSetValue (l, r) {
return passApiCall('LMSSetValue',l,r); var val = passApiCall('LMSSetValue',l,r);
if(typeof val === "undefined") {
queueCall('LMSSetValue', l, r);
val = r;
}
return val;
} }
function LMSGetValue (s) { function LMSGetValue (s) {
return passApiCall('LMSGetValue',s,''); return passApiCall('LMSGetValue',s,'');
} }
function LMSGetLastError () { function LMSGetLastError () {
return passApiCall('LMSGetLastError','',''); var val = passApiCall('LMSGetLastError','','');
if(typeof val === "undefined") {
val = "0";
}
return val;
} }
function LMSGetErrorString (s) { function LMSGetErrorString (s) {
return passApiCall('LMSGetErrorString',s,''); var val = passApiCall('LMSGetErrorString',s,'');
if(typeof val === "undefined") {
val = "No Error";
}
return val;
} }
function LMSGetDiagnostic (s) { function LMSGetDiagnostic (s) {
return passApiCall('LMSGetDiagnostic',s,''); return passApiCall('LMSGetDiagnostic',s,'');
} }
function LMSCommit (s) { function LMSCommit (s) {
return passApiCall('LMSCommit',s,''); var val = passApiCall('LMSCommit',s,'');
if(typeof val === "undefined") {
queueCall('LMSCommit', s, '');
val = r;
}
return val;
} }
\ No newline at end of file
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