Created
June 5, 2013 16:58
-
-
Save alroman/5715465 to your computer and use it in GitHub Desktop.
Prevent Moodle form submission if user session timed out. The form submission is stopped and an ajax call is made to the server to check that the user's session is still valid. If the session is valid, then the form submits, otherwise the user gets a login prompt and allowed to submit the form once they've logged in again. Currently activated fo…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Form submit login check | |
$string['longincheck_login'] = 'Your session has timed out. In order to save | |
your work login again and save your changes.'; | |
$string['logincheck_idfail'] = 'Your user ID does not match! This form has been ' . | |
'disabled in order to prevent an erroneous submission. ' . | |
'Save your work and reload this page.'; | |
$string['logincheck_networkfail'] = 'There was no response from the server. ' . | |
'You might be disconnected from your network. Please reconnect and try again.'; | |
$string['logincheck_success'] = 'You\'re logged in. You can now submit this form.'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* YUI module to prevent form submission if user is not logged in | |
* | |
* This will attach itself to all '.mform input[type="submit"]' buttons and prevent | |
* the 'click' event. Will then poll the server to see if user is still logged in. | |
* | |
* If user is logged in, sumission continues, else | |
* form submission is halted and the user is given option to login | |
* | |
*/ | |
YUI.add('moodle-local_ucla-logincheck', function(Y) { | |
var SITE = M.cfg.wwwroot; | |
var USERID = null; | |
var MESSAGES = { | |
LOGIN: M.util.get_string('longincheck_login', 'local_ucla'), | |
IDFAIL: M.util.get_string('logincheck_idfail', 'local_ucla'), | |
NETWORKFAIL: M.util.get_string('logincheck_networkfail', 'local_ucla'), | |
SUCCESS: M.util.get_string('logincheck_success', 'local_ucla') | |
} | |
var PAGE = { | |
LOGIN: '/login/index.php', | |
LOGINCHECK: '/local/ucla/logincheck.php' | |
} | |
// Load our namespace | |
M.local_ucla = M.local_ucla || {}; | |
// Attach script | |
M.local_ucla.logincheck = { | |
init: function(config) { | |
USERID = config.userid; | |
// Target forums: | |
var forums = Y.one('.mform input[name="_qf__mod_forum_post_form"]'); | |
if(forums != null) { | |
// Grab all forms on the page.. | |
var forms = Y.all('.mform'); | |
// Attach event handlers to all forms | |
forms.each(function(form) { | |
// Grab all the submit buttons | |
var buttons = form.all('input[type="submit"]') | |
// Hijack the 'click' handler for buttons | |
buttons.on('click', function(e) { | |
// Caputure default event... | |
e.preventDefault(); | |
// Poll the site to see if user is logged in.. | |
Y.io(SITE.concat(PAGE.LOGINCHECK), { | |
method: 'GET', | |
on: { | |
success: function(id, result) { | |
var json = Y.JSON.parse(result.responseText); | |
// Check status | |
if(json.status) { | |
// If all good, then continue click | |
// First remove the event handler | |
e.target.detachAll(); | |
// Then simulate click for default behavior | |
e.target.simulate('click'); | |
} else { | |
// User is not logged in... | |
if(!form.hasClass('attention')) { | |
// Create alertbox with login button | |
// Build alertbox node | |
var alertbox = Y.Node.create('<div><p>' + MESSAGES.LOGIN + '</p></div>'); | |
alertbox.addClass('alert').addClass('alert-warning'); | |
// Add login button | |
var button = Y.Node.create('<button>Login</button>'); | |
button.addClass('btn').addClass('btn-success').on('click', function(e) { | |
e.preventDefault(); | |
// Pop up window invoke.. | |
M.local_ucla.logincheck.popupwin('user-pop-login', form.getAttribute('id')); | |
}); | |
// Attach button | |
alertbox.append(button); | |
// Display alertbox | |
form.append(alertbox); | |
// Draw attention to the form | |
form.addClass('attention'); | |
} | |
} | |
}, | |
failure: function() { | |
// Create network failure alert | |
var failalert = Y.Node.create('<div>' + MESSAGES.NETWORKFAIL + '</div>'); | |
failalert.addClass('alert').addClass('alert-danger'); | |
form.append(failalert); | |
} | |
} | |
}); | |
}); | |
}); | |
} | |
}, | |
popupwin: function(windowname, formid) { | |
// Pop up window vars.. | |
var url = SITE.concat(PAGE.LOGIN); | |
var name = windowname; | |
var params = 'toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1, width=500,height=500,left=200,top=200'; | |
var popup = window.open(url, name, params); | |
// Poll every second to close window as soon as user logs in... | |
var timer = Y.later(1000, Y, function() { | |
// If user's closed window, stop timer | |
if (popup.closed) { | |
timer.cancel(); | |
return; | |
} | |
// Poll session var to see if it's active | |
Y.io(SITE.concat(PAGE.LOGINCHECK), { | |
method: 'GET', | |
on: { | |
success: function(id, result) { | |
var json = Y.JSON.parse(result.responseText); | |
// If user is logged in.. close the popup | |
if(json.status) { | |
// Grab the form | |
var form = Y.one('#' + formid); | |
// Check that userid is the same | |
if (json.userid == USERID) { | |
// Reset the session key or form will be rejected | |
form.one('input[name="sesskey"]').set('value', json.sesskey); | |
// Y.one('#' + formid + ' input[name="sesskey"]').set('value', json.sesskey); | |
// Close the pop-up | |
timer.cancel(); | |
popup.close(); | |
// Delete the popup notification | |
form.all('div.alert').remove(true); | |
form.removeClass('attention'); | |
// Add a 'success' notification | |
var successalert = Y.Node.create('<div>' + MESSAGES.SUCCESS + '</div>'); | |
successalert.addClass('alert').addClass('alert-success'); | |
form.append(successalert); | |
} else { | |
// Not the same USER, so disable form | |
form.one('.alert').removeClass('alert-warning') | |
.addClass('alert-danger') | |
.setHTML(MESSAGES.IDFAIL); | |
// Disable submit | |
form.all('input[type="submit"]').set('disabled', 'disabled'); | |
} | |
} | |
} | |
} | |
}); | |
}, '', true); | |
// Close window after 30 secs? | |
Y.later(30000, Y, function () { | |
timer.cancel(); | |
popup.close(); | |
}); | |
} | |
} | |
}, '@VERSION@', { | |
requires: ['node', 'io', 'json', 'event', 'node-event-simulate'] | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Checks if user's session is still active | |
*/ | |
require_once(dirname(__FILE__) . '/../../config.php'); | |
$obj = new stdClass(); | |
$obj->status = false; | |
if(isloggedin() && !isguestuser()) { | |
global $USER; | |
$obj->status = true; | |
$obj->sesskey = $USER->sesskey; | |
$obj->userid = $USER->id; | |
} | |
// Return JSON response | |
header('Content-Type: application/json'); | |
echo json_encode($obj); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Attach login check | |
// This prevents forms from being submitted when the user is not logged into site | |
$PAGE->requires->yui_module('moodle-local_ucla-logincheck', | |
'M.local_ucla.logincheck.init', | |
array(array('userid' => $USER->id))); | |
$PAGE->requires->strings_for_js( | |
array( | |
'logincheck_success', | |
'longincheck_login', | |
'logincheck_idfail', | |
'logincheck_networkfail'), | |
'local_ucla'); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment