Warn user when new data is inserted on database - php

I don't know how to search about this so I'm kinda lost (the two topics I saw here were closed).
I have a news website and I want to warn the user when a new data is inserted on the database. I want to do that like here on StackOverflow where we are warned without reloading the page or like in facebook where you are warned about new messages/notifications without reloading.
Which is the best way to do that? Is it some kind of listener with a timeout that is constantly checking the database? It doesn't sounds efficient...
Thanks in advance.

You need javascript ajax and json and callback function to check constantly. It can be done by push services but PHP is bad with that and you need websockest, etc. facebook uses timeout calls. not sure for the stackoverflow
refreshInterval = 500
refreshTimeout = setTimeout( getNotificationCounts, refreshInterval );
function getNotifications() {
$.ajax({
url : 'path_to_your_php',
type : 'POST',
data: //put for exampel user_id but it cvan be handled by sesion as well
dataType : 'json',
success : function(data) {
alert('You have'+ data.total +' new messages')
refreshTimeout = setTimeout( getNotificationCounts, refreshInterval ); //this will check every half of second
}
});
}
then in PHP, for example you have a flag in database with which you check if data is new to teh databse. Mind the formatting and to proper sql escape
$result=mysql_query("SELECT count(*) as total from myTable where user_id=$_POST['user_id'] AND is_read=0");
//note instad of $_POST you can use session if users are logged in, or however you are handling it
$data=mysql_fetch_assoc($result);
echo json_encode($data)
;
After that you can create another ajax call that marks messages as read once user clicks on them. or opens a dialog listing or wahtever
mysql_query("UPDATE myTable WHERE user_id=$_POST['user_id'] SET is_read=1");

Related

Jquery - How to call a function only if a new row is inserted in database

I have a div which contains comments for a post ... when user add a comment the div containing comments get updated immediately ( i have set a function which is called when user press enter )
Here Is my code for that :
$(document).on('keydown','.addComment',function(e){
var id = $(this).attr('id').match(/\d+/);
var p_id = Number(id);
var comment_box = '#comment_box_'+id;
var content = $(comment_box).text();
if (e.which === 13 && e.shiftKey !== true) {
content = content.replace(/\s\s+/g, ' ').replace(/\n/g, '<br>');
if (content.length > 0 ) {
$.ajax({
type : 'POST',
url : 'update.php',
data: ({
content: content,
id: p_id,
act: "add_cmnt"
}),
success : function()
{
update_ca("comment_area_"+id, true);
}
}); //End of Ajax
}
return false;
}
});
but a user logged in from another account must have to refresh the page to see new comments ... now what i want to do is that all users see the latest comments without refreshing the page i.e when ever a new comment is posted by any user the div containing comments should be updated ... now one way is to do this is that a function is called out after every 10 seconds which refreshes the div via ajax
Here is code :
setInterval(function(){update_comment_area();}, 10000);
this line of code refreshes the comment area after every 10 seconds but i want this function to be called only if a new row ( comment ) is inserted into a database
can anyone help me that how this can be done ??
Create a function that checks for a new row in the database i.e checkNew().
Then try:
if (checkNew()) {
refreshAjax();
}
Note: for the checkNew(), if a new record has been inputted, return true;
Else return false;
Here is a way to implement the checkNow():
Let it retrieve the value gotten from a PHP page that performs the SQL: SELECT lastupdated FROM commentTable ORDER BY id DESC LIMIT 1.
What that does is that it retrieves the last value in the commentTable which would obviously be the last inserted comment. Then update your page with intervals. The comment will continue to change as long as more comments are being added
Since it sounds like you already have an event for the submission of a comment, and assuming you're using javascript to push the comment to the server:
You can just use a callback and have it refresh then. Of course, that would only show up for the user that submitted the comment.
Example for that: JQuery Ajax calls with callbacks
Since you haven't mentioned your back-end coding language or database structure there are only a limited amount of suggestions I can give. However, one that would work would be to use AngularJS, or Socket.io to establish 2-way binding.
UPDATE:
Based on your code and how you're calling it I'm going to assume that update.php has the ability to know whether the record (comment) was added successfully. Once it's been added, have update.php set a global javascript variable to a new value (increment it, use a random number, doesn't matter as long as the value changes)
Then setup an object.watch() that will do your ajax call to update the comments when that variable changes. This is probably the simplest way to do it without using something like socket.io or angular.
How to use object.watch in javascript

Is it possible to 'echo' a sequence of responses from an ajax call

I'm learning and experimenting with jquery/ajax as I develop a website. I have a page that updates a database. I would like a 'sequence' of responses to display on the screen when the user submits their data (I've seen this done on many other sites).
For instance... user submits form and the page displays:
Received Input
Checking Database - recond number xy
Updating Database
Retrieving Information
etc etc
This is just an example but you get the idea.
I have an ajax call that is initiated on 'click' of the submit button (getFormData just serialises all the form data for me and works fine):
var toSend = getFormData($upgrade_db_form);
var formMessageBox = $("#displayResults");
$.ajax({
url: ajaxurl,
data: {
action: "database_action",
formData : toSend
},
type: 'POST',
dataType: 'TEXT',
beforeSend: function() {
//$form.fadeOut('slow');
formMessageBox.html("starting it up");
},
success: function (data) {
formMessageBox.empty();
formMessageBox.html(data);
error: function (xhr) {
// formMessageBox.html("Oops error!");
}
});
I have a function which gets called by ajax:
function upgrade_database_function() {
echo "testing ";
for($i = 0; $i < 99; $i++) {
echo "percent complete ".$i."%";
}
echo "done ";
die(); // this is required to return a proper result
}
I'm using Wordpress and all the ajax side of things works fine, it passes the form data correctly etc, it's just that I get one long output as though it's cache'ing all the echo's up instead of outputting them in sequence.
I've gone through the jquery ajax documentation and couldn't find how to make it behave the way I want it to. I can live with it the way it is but I think it would look a lot better if I could get it working the way I would like.
Can this be done this way or do I need lots of sequential ajax calls to make it work?
I don't know PHP, but i'm guessing that the echo is just writing to the response buffer... so when all the echos are done the whole response will be returned and you would get the effect that you are seeing... You would need to go with a polling system or something along those lines to get the latest status' from the server and display them I would think... Maybe there is some system in PHP that allows this, but as I said, I don't know PHP.
An Example of Long Polling can be found in this article.
http://www.abrandao.com/2013/05/11/php-http-long-poll-server-push/
WARNING: You may have to do some manual managing of locking of the session in PHP so that your long running call doesn't lock your polling ajax calls: See here:
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
Note that you would likely be wanting to:
create one ajax call that starts the execution of some coded that will take a while... you could put messages that have been generated into a session variable for example in a list of some sort. You would need to lock/unlock the session as mentioned to prevent suspension of AJAX polling calls.
you would create a polling method like in the article that might check the session every 500ms or something to see whether there are any more messages, lock the session, remove those messages and return those messages to the client side and display them.
WARNING: Again, I'm not a PHP person, I may have done this once in my life in PHP (can't remember exactly) but I may be wrong and this may not work, from what I've seen though it looks like it is achievable. Hope this gets you on your way!

Delete an entry from db on PHP page exit

I have a php page in which a user tries to find online people.
There a search button, clicking on which, an entry is made for the current user in the database and the control goes inside a loop, where every 5 secs a search is made in the database to find if a new entry has been made, if an entry is found then the details of the partner is shown to him.
I want that if the user exits or navigates away from the page before a partner is being found, then his entry must be deleted from the db.
I am trying to store the 'id' created against the user inside a session variable, make an ajax call and delete the entry, but somehow this concept is not working.The data is not getting deleted. Is this because of the loop which is still finding the user or something else, m not able to get it.
Can anyone tell me what is going wrong with my approach ?
A code snippet that I am using is hereby
window.onbeforeunload = function() {
funcDeleteonexit();
return "Are you sure you want to navigate away?";
}
function funcDeleteonexit(){
$.get("functions.php",{
data:"delete"
},function(data,status){
});
}
Inside my functions.php, I have
if($_GET){
if ($_GET['data']=="delete"){
echo deletefromDb();
}
}
function deletefromDb() {
$mysqli = new mysqli("localhost", "root", "", "test");
/* check connection */
if (mysqli_connect_errno())
{
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$currentid = (int)$_SESSION['currentId'];
$query1 = "delete from test where id =". $currentid;
$mysqli->query($query1);
$mysqli->close();
return $currentid;
}
If you want something done when someone exits the page, this will in most cases give you trouble if you want a specific event to be fired then. There will be cases a browser cannot fire the event (p.e. client crash etc.).
Therefore I'd suggest a different approach. Control this from the server side, and don't rely on the users browser or input.
Firstly, you can poll your data while regularly firing Ajax events from the browser. You've not stated this, but I think you do something like this:
function yourrequest(){
$.ajax({
type: "GET",
url: "your/php/script.php",
success: function(data){
// do something, p.e. update a div
}
});
};
setInterval(yourrequest, 5000);
(Please don't tear this code sample apart, its just to show the basics).
On the server side, you already have the users id somewhere in your database. Add a timestamp field to this table (call it last_request or something like that). Everytime you send some data to the client, check if there are users with a last_request below your desired threshold, and delete those ids. No need to wait for a specific event then.
This needn't be done exactly there, you can also do something different, p.e. a cleanup job cronned every 5 minutes or so which does this seperately to not disturb the users request at all.
I'm suggesting that browser just not sending ajax, or interupting it.
So try to make your AJAX request synchronous. For JQuery seems to be set async parameter to false
$.get("functions.php",{
data:"delete",
async : false
},function(data,status){
});

Upating mysql fields asynchronously with ajax when "Like" is clicked

The question is fairly simple. Whenever user clicks on "like" I want to use javascript to update the mysql database through ajax. I have tried all means bit have found nothing helpful. I know I will also need a server side script but the ajax is the main issue.
Here is the counter code I set up.
document.observe("dom:loaded", function()
{
$("likeForumLink").onclick=processForumLike;
});
function processForumLike(event)
{
var numberOfLikes=parseInt($("hiddenLikes").value);
numberOfLikes+=1;
$("hiddenLikes").value=numberOfLikes+"";
this.innerHTML="You liked this";
if(numberOfLikes==1)
{
$("numberOfLikes").innerHTML="("+numberOfLikes+" like)";
}
else
{
$("numberOfLikes").innerHTML="("+numberOfLikes+" likes)";
}
var likes=$("hiddenLikes").value;
new Ajax.Request("seeForum.php?id=$("subjectId").value", {
method:'get',
parameters:{hiddenLikes:likes},
onSuccess: ???? //Don't know
onComplete:??? //Don't know
on Failure:???? //Don't know
});
}
And then I can use my server side script as follows.
P.S. It lies in the same page "seeForum.php?subjectId=$("subjectId").value"
<?php if(isset($_GET["hiddenLikes"]))
{
$updateQuery="UPDATE `subject table` SET `likes`='".$_GET["hiddenLikes"]."' where `subjectId`='".$_REQUEST['subjectId']."' ";
$result=mysql_query($updateQuery);
checkConnect($result,"query of $updateQuery");
?>
Please help. All my work has come to a halt.
First of all, you shouldn't be using a GET request to update data, that should be a POST. And this:
"seeForum.php?id=$("subjectId").value"
doesn't do what you probably think it does. What it does do is cause a syntax error because it looks like "x" x "x" to the JavaScript interpreter and that's not JavaScript. I'm not sure which JavaScript library you're using (Prototype perhaps?) but I think you probably want to put all your parameters into parameters to avoid having to worry about URL encoding and things like. Furthermore, there's no reason to tell the server how many "likes" you already have and there is a good reason not to: someone might have "liked" the page while you're looking at some the number of likes you currently have will be wrong; so hiddenLikes isn't needed at all.
Something like this would be better on the JavaScript side:
new Ajax.Request("likeIt.php", {
method: 'post',
parameters: { id: $('subjectId').value },
onSuccess: function(transport) {
// Update the "likes" label with something like this,
// I'm not that familiar with Prototype though so I'm
// guessing.
$('likes_label').update(transport.responseText);
},
onComplete: ???? // The function to call when it has finished.
onFailure: ???? // The function to call when it doesn't work.
});
And then, in the PHP, just send a simple UPDATE to the database to increment the number of likes in likeIt.php, something like this:
<?php
# Perform whatever authentication you need...
if(isset($_POST["id"])) {
# Set up your database connection and then...
$result = mysql_query("UPDATE `subject_table` SET `likes` = `likes` + 1 WHERE `subjectId` = '" . mysql_real_escape_string($_POST["id"]) . "'");
# Check $result and send some data back to the client (if desired), if
# you send something back then the onComplete, onFailure, and onSuccess
# JavaScript functions would be responsible for doing something with it.
}
# Send back the updated number of "likes" as text/plain.
?>
Well thinking it through, if the user clicks on like, all you really want to do is increment the like counter in the page itself. You can do this in the onComplete: function(){ increment the like counter }. If some kind of error does occur, i don't think you would want to display it to the user, depends on how you want to handle that part, many ways to do it, you could log the error.

How to deal with session timeouts in AJAX requests

I'm sure you're all familiar with the voting systems that use AJAX (Um... look right over there <----)
I have something similar and when you vote up or down it uses AJAX to request the new value from votes.php. The problem is that I am using a session to get the userid so a person can only vote once. What happens if they sit on the page for an hour and then vote so the session is no longer there? What would be a good way of handling this situation? Should I redirect their page to the login screen? If so, how can I do that from the votes.php page that is being referenced by the AJAX request? Am I overlooking a good way of handling this situation? Any advice would be helpful.
Consider returning an http status of 401, and a JSON object detailing the reason. If you're using jQuery, that'll drop you to the error() callback, which you can then parse your object.
$.ajax({
data: {},
dataType: 'html',
success: function(data) {
// do whatever here
},
type: 'POST',
url: 'myserver.com',
error: function(XMLHttpRequest, textStatus, errorThrown) {
// XMLHttpRequest.responseText has your json string
// XMLHttpRequest.status has the 401 status code
if (XMLHttpRequest.status === 401) {
location.href = 'login.php';
}
}
});
I'm not familiar with PHP anymore, but this should work for just about any environment. You may have to suppress any automatic login form redirection though. In asp.net mvc the framework will see the 401 and push the default login form back, with a status of 200.
You should only store a link to the users identity in the session. Use sessions to identify a user as x and then get user x's information from the database.
If your problem is with users sessions timing out then you should reconsider how you're using your sessions. Perhaps make them last until the browser closes? If you really want to make them a duration, then perhaps ping the server in intervals to keep the session alive.
Decide in your php script whether or not the user should be able to vote. If the session isn't set, or if they have already voted, return a message that you can identify with on the client side. If they already voted perhaps return "voted":"true" in a JSON object. Use JS to parse this object and understand what it means, taking the appropriate action. If the session isn't set, perhaps return "session_set":"false", and then make javascript redirect with a window.location = "login.php" etc.
Only increment the counter for the user on a successful return of a counted vote.
This is an old thread, but I wanted to share my solution that is working really well.
In my framework the system redirects the user to the login form any time they try to access a page and the session has timed out or is not valid.
I added to the top of the login form the following html comment:
<!--LOGINFORM-->
I created a wrapper for jQuery's $.ajax function which checks for this string on every request, and if it is there it shows a dialog popup saying that their session has timed out.
You can use this by just calling:
ajax.get('http://someurl.com', function(data){
//Do stuff
});
Hope it helps someone.
var ajax = {
check_login : function(resp){
if (resp.substring(0, 16) === "<!--LOGINFORM-->"){
// Show a popup or redirect them to login page!
return true;
}
return false;
},
get : function(url, success){
if (typeof data =='undefined'){
data = null;
}
$.ajax({
url: url,
type : 'GET',
success : function(resp){
if (!ajax.check_login(resp)) {
success(resp);
}
},
});
}
};
You structure the Javascript code that makes the Ajax request to accept a special result (say, -1 where a >=0 number would normally be, such as, a count of votes) to mean "sorry bub, you're timed out" and redirect to the re-login page (which can take as an optional parameter a message explaining to the user they timed out, &c).
You could create a javascript function that could ping the server every 10 minutes via something like
setTimeout("Ping()", 60000);
If you want to navigate the user to the login page if they connect with a faulty session then I would first verify the session and if it fails send a
header("Location: ...");
http://ca2.php.net/manual/en/function.header.php
From a user perspective, the best solution is to pop up a message and login form, saying something like "You are not logged in or your session timed out". Digg does this very well.
As for the actual AJAX implementation, swilliams' 401 suggestion is solid. Alternatively, you can simply return a specific string on failure.

Categories