I want to make a user status system and i was thinking to have in my database a datetime field called last_active and update that field automatically with ajax with current time.
Then i check minutes between last_active and current time.. to tell if the user is online, inactive and offline..
Is this a good technique? and what happens if the user for example has the site open but is doing something else?
Is there a way to fire ajax request only if the user is viewing the page?
Your current method is a good technique to do, and the way to go,
you can check with focusin and focusout function with jquery to check if user is currently active on document or not,
$(document).ready(function(){
$([window, document]).focusin(function(){
// start the ajax requests
}).focusout(function(){
// stop the ajax requests
});
});
you should take variable that will set to true in focusin function and, will set to false in focusout function. now the continues ajax request function will fire only if the variable is set to true.
This is a very good way to check for activity. You can fire Ajax requests when the page is in focus only. I would consider using the mousemove event or similar, but also the blur/focus events can prove useful.
When the mousemove event is fired, set a variable to true and check thet variable before doing your Ajax request. Don't forget to reset it to false between each Ajax call.
Related
I am creating an event in which if one user submitted the problem correctly all the users will be forwarded to the next question. For this, I have implemented by storing a variable in the database for knowing if the solution is submitted or not. Problem is that Like 100 people will be playing the same event at the same time so for all the users we have to check repeatedly in the database that is the problem submitted or not which kind of seems hectic.
Is there any better way to implement this like having a variable which is common to all the users?
You could use ajax in your client side to check for updates every 5 seconds.
When a user updates the correct answer you can store the answer in a cache like memcache / redis. The function the ajax request triggers will see if there is a answer in the cache, and it will return true. In your client side JS you can check if the returned response of the AJAX was true and then proceed to the next question.
So for example you will send a ajax request to /getupdate with a ID of the current session or similar, the /getupdate page will execute a function which will look for the ID in the caching server, if the ID exists it means the question is answered so it will either return TRUE or the value of the answer. In the client side, you can check if the value is FALSE and if it is, don't do anything, if they value is not FALSE, you can have the next question updated, or show the answer to the user.
You can make use of Web Sockets(like Ratchet) and broadcast to the whole server. Each client connected will listen the message and you will have to define a state storing current question, meanwhile you can update the database storing the current order of question in case if anyone disconnects you can assure everyone gets the same order upon reconnecting.
Making AJAX calls will also do if you don't mind the delay between timeouts, which in your case does matter.
I have form, let's say it's on index.php. On submit, it goes through process.php, then finishes on thanks.php. I want to trigger an Analytics Event so I can track my form (no I don't want to use a URL Destination). If I put the Event code on thanks.php, I'm concerned that if people refresh the page, it will re-trigger and give me bad results. So, I want it to trigger from process.php somehow. At the end of process.php, I set the header like this:
header('Location: /thanks.php');
This is the code for triggering the Event:
_gaq.push(['_trackEvent', 'ClaimDomain', 'ConfirmationPage']);
Is there some way of sending the JavaScript call along with the header, so that it only gets processed as we leave process.php, and not when we refresh thanks.php?
Thanks for your help :)
Not really, PHP is server-side, Javascript is client-side.
From reading about this though, it sounds like it may be a non-issue:
Unique events are incremented by unique actions
Any time a user interacts with an object tagged with a particular
action name, the initial interaction is logged as one unique event for
that action name. Any additional interaction with the same action
trigger for that user's session will not contribute to the unique
event calculation for that particular action. This is true even if the
user leaves that object and begins to interact with another object
tagged via the same action name.
Source: Event Tracker Guide - Actions.
So GA will know if they happen to land on the page twice and it will not count as 2 unique events.
Based on my comment above and researched by #drew, it's a non issue.
If you also want to track the goal. Use a "head match" to do so.
http://support.google.com/googleanalytics/bin/answer.py?hl=en&answer=72285
Is it possible to check on the click of a link (html) whether a php session has been set? I am trying to stop a link being clicked should a user not be logged in. Thanks
I think you've got your logical sequence of events mixed up. You check the existence of a php session before the page is even served.
Once a link is on the page you cannot directly prevent it from being used, unless you add an on-click listener or handle it with javascript.
You can use ajax for that. Simply send ajax request to the server and then check if your session is set.
For convenient notification purposes, not secure information purposes:
I have javascript polling for new information while logged in. I want it to stop while logged out. What is the best way to let javascript know about the logged-in/logged out status?
Run a javascript function on login, and one on logout (which might get skipped if they navigate away and come back directly)?
Run a poll periodically to check for access to secure (logged-in-only) information and skip further polls if that access isn't available?
Another option that I haven't found yet?
I'm running php server-side, if matters.
The Cookie approach should work. The other thing you can do is create a JSON page that returns true or false if the user is logged in. Then check that before your other code, if it's logged in do what you do, if not do something else, perhaps redirect to Login page?
In jQuery it goes something like this:
$.getJSON("/login/is_logged", function(json) {
if(!json.User.logged) {
window.location = '/login/form/';
}
});
The JSON page (url /login/is_logged) returns this:
{"User":{"logged":true}}
Here's the link to $.getJSON.
Set a cookie on login/logout actions: e.g. logged=1 :)
Have javascript poll as normal, and when it tries to poll while logged out, return an error.
You could just set a Javascript boolean at page load time: true if the user's logged in, and false if they're not.
You can add a class="loggedin" or id="loggedin" to the <body> or <html> tags, and read these with the DOM / jQuery functions.
The class of the HTML tag can be read with: document.documentElement.className.
Since your server-side PHP already knows if the user is logged in, or not, it could add the proper "logged in" <script> code in the page too.
Ok, here is what I decided to do:
Keep a boolean that corresponds to
logged in/logged out state (1 or 0).
Login toggles 1.
Logout toggles 0.
If the existing polling checks the api
and gets false return values because
a logout has occurred, it will toggle the boolean to 0 as
well (after
either 1 or two false information
checks).
Once the boolean is 0, no further polling
will occur until a login event toggles it back to 1.
A while back, online apps used to say, "do not click submit more than once." That's gone now, right? How do you guard against that in, say, PHP?
One solution I'm using involves putting a variable in the Session, so you cannot submit to a page more than once every 10 seconds. That way the database work will have completed so the normal checks can take place. Obviously, this feels like a hack and probably is.
Edit: Thanks everybody for the Javascript solution. That's fine, but it is a bit of work. 1) It's an input type=image and 2) The submit has to keep firing until the Spry stuff says it's okay. This edit is just me complaining, basically, since I imagine that after looking at the Spry stuff I'll be able to figure it out.
Edit: Not that anyone will be integrating with the Spry stuff, but here's my final code using Prototype for the document.getElementByid. Comments welcome!
function onSubmitClick() {
var allValid = true;
var queue = Spry.Widget.Form.onSubmitWidgetQueue;
for (var i=0;i<queue.length; i++) {
if (!queue[i].validate()) {
allValid = false;
break;
}
}
if (allValid) {
$("theSubmitButton").disabled = true;
$("form").submit();
}
}
For some reason, the second form submit was necessary...
You should do both client- and server-side protections.
Client side - disable button e.g. by jquery as cletus has described.
Server side - put a token in the form. If there are two submissions with the same token, ignore the latter. Using this approach, you are protected against CSRF.
This is an excellent example of what jQuery is useful for (you can do it in any Javascript though). Add this code:
$("form").submit(function() {
$(":submit",this).attr("disabled", "disabled");
});
And it disables submit buttons once clicked once.
As others have noted, you can disable the button. I like server-side checks better, though - JS may be disabled, user might hit refresh (although if you're properly using POST that will generate a warning), etc.
You can add a timestamp to the form and track it in the session - require the POSTed timestamp be greater than the tracked one. That will prevent most double-posts without noticeably affecting the UI.
It's also important to note that PHP's default behaviour if it detects the user has "cancelled" the request (by closing the browser, pressing "stop", or perhaps pressing Submit a second time) is to stop executing the script. This is undesirable if you're doing some sort of lengthy transaction. More details here.
I would think the best option is to let the PHP script first set a flag in the session array to indicate that it is processing a form. That way a second request can be set to wait until the original request has completed (use a sleep call server side waiting for the flag to clear).
It is important not to interfere too much with the submit button and process, because the nature of the web is one of uncertainty; the user may want to click a second time if no answer has arrived, and you don't want to lose their data. That could occur if the first request is lost and you have disabled their only way to submit (and therefore store) the data.
One cleaner solution is to submit the request, and use javascript to display a message saying 'Processing', so that the user can see that something is happening, but they are not prevented from re-submitting the data.
One solution is to immediately disable the button on click using Javascript. This obviously relies on javascript being on on the client browser.
The server side trick is better since it will catch race conditions between multiple browser windows if the user is editing the same record twice.
I've done a simple version of this with javascript when I was working with ASP.NET AJAX but it should work in any case where your button has an actual ID.
I take the following steps in the button onclick event:
Disable the button that triggered the onclick event
Store the button id in a magic variable closureId that I can reference later via closure
Use the setTimeout function to execute a dynamically defined callback after the specified number of milliseconds (5000ms = 5 seconds)
In the callback function I can reference the magic closureId and re-enable the button after the timeout
Below is a simple HTML button you can throw into a test.html file by itself to play with:
<input id="btnTest" type="button" value="test" onclick="var closureId=this.id; this.disabled = true; setTimeout(function(){document.getElementById(closureId).disabled = false;}, 5000);>
You should still be doing server-side checks as others have suggested but in my own instance the submit also did a server side validation of business logic. The user would submit their form and then have to wait to see if the business logic on the server-side would actually allow that entry or not. It also helped out during development when I could take my server down and still have the form submission fail decently.
Note I call that closureId variable 'magic' because I don't have a firm grasp of how it works--
I just realized that calling this.id didn't work because this is a reference to the timeout function that is executing the dynamic callback function and doesn't have any sort of DOM id.
I couldn't find any other way to get a reference to the original event (this.this.id doesn't work) but lexical scoping is somehow allowing me to still access the closureId variable as it was defined at the time of the original button click.
Feel free to fix/comment if you know of a better way!
I usually disable the submit button after it's pressed. Session throttling is good against direct attacks, but I do not want to mix interface logic where it doesn't belong.