Skip to content

Instantly share code, notes, and snippets.

@alroman
Created June 5, 2013 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alroman/5715465 to your computer and use it in GitHub Desktop.
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…
<?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.';
/*
* 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']
});
<?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);
<?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