I'm attempting to make a notification system that notifies users when they are assigned to a ticket, or when a new ticket is added to the database.
The system itself, that I already have, works except that it only sends the notification to the first user who receives the ajax request. Is there any way to make it so that everyone who is suppose to receive the notification, actually receives the notification?
My code:
javascript:
function checkUpdates()
{
$.ajax({
type: "POST",
url: 'ajax/checkDB.php', // a webservice or other URL that queries the database
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
console.log('Connected and executed PHP page... '+data);
if (data.hasChanged == "true") {
playSound('img/notif2');
notifyAdmin();
console.log('Updated Tickets Page...');
$("#contents").load("dynamic/tickets.php");
$("#contents").fadeTo("fast", 1);
}
if (data.newAssigned == "true") {
playSound('img/notif2');
notifyUser();
console.log('Updated Tickets Page...');
$("#contents").load("dynamic/tickets.php");
$("#contents").fadeTo("fast", 1);
}
}
});
}
$(document).ready(function() {
setInterval("checkUpdates()", 3000); // Calls the function every 3 seconds
});
My php script (checkDB.php):
<?php
include("../static/config.php");
session_start();
header("Content-Type: text/json");
$result = mysqli_query($con,"SELECT notify FROM tickets WHERE notify='0'");
$row_cnt = mysqli_num_rows($result);
if($row_cnt > 0) {
$hasChanged = 'true';
mysqli_query($con,"UPDATE tickets SET notify='1' WHERE notify='0'");
} else {
$hasChanged = 'false';
}
$result2 = mysqli_query($con,"SELECT notify,Assigned FROM tickets WHERE Completeness='1' AND notify='1'");
$row_cnt2 = mysqli_num_rows($result2);
if($row_cnt2 > 0) {
while($row2 = mysqli_fetch_array($result2))
{
if(strcmp($_SESSION['Name'],$row2['Assigned']) == 0) {
$newAssigned = 'true';
} else {
$newAssigned = 'false';
}
}
mysqli_query($con,"UPDATE tickets SET notify='2' WHERE Completeness='1' AND notify='1'");
} else {
$newAssigned = 'false';
}
echo json_encode(array('newAssigned' => $newAssigned, 'hasChanged' => $hasChanged));
?>
Here is a rundown of my exact intentions:
User logs into system, and is given administrative rights if granted.
User loads the tickets page, which lists all the tickets along with this javascript that I gave you
the javascript loads checkDB.php every 3 seconds, basically running a check against the database for a 'notify' value of 0, and if at least 1 exists, is updated in the database to '1' and is returned as true to the ajax call - which sends out notifications.
Again this works for the 1st user who is loaded into the page, but after that, obviously there are no more 'notify=0' in the database as they have already been updated, so they are not shown the notification.
It was requested that I share my database structures.
tickets:
UniqueID - Unique ID per ticket (always unique)
Requester - Whoever submitted the ticket.
Problem - Description of the given issue.
Assigned - User who is assigned to the ticket.
Completeness - The level of completeness (0-4)
Times - Times listed for ticket start, assigned, etc
notified - Used in old ticket system (I plan to get rid of it)
Urgency - Selected by requester, how urgent the ticket is
Location - Location in our warehouse assistance is needed.
FollowUp - currently not in use, will be used to submit follow ups.
isProject - (0-1) is project or not
additionalTechs - Lists additional users on a ticket (Not important for question)
notify - (0-2) at 0, ticket is new and notif should be sent to admins which should set this to 1, when it is 1 it should send a notif to users that are attached to the ticket.
Techs Database:
UniqueID
Username
Password
Name
Level
Disabled
LastTimeSeen
needsNotify (Used in old system, plan to remove)
I'm really stuck here.
You can make it with websockets, or socket.io.
Then the js of multiple clients will connect with that socket will notify all connected people about they ticket
You can change your update statement to something like:
UPDATE tickets SET notify='1' WHERE notify='0' and Assigned = ''//some user id passed
Related
I am creating a system where the objective is that only one person per user can access the system, for this I have in my DB two tables called: users and accesses What I am doing is that when person 1 logs in, it is saved in my DB the id of the session in the two tables, if person 2 with the same user tries to access then the first person to log in takes it out of the system. I do this with help with AJAX, comparing if the last user who started has the same session id then he can navigate without problem, if he does not close session.
The problem is that I make this ajax request every 10s, but I would have problems if 10,000 people or more log in, then the request will be sent to the server every 10 seconds and this could saturate the server.
Try an active field if the session is equal to 1 and if the session is equal to 0, then discard this since if the user closes the browser then I never close session and the person will not be able to access, I also tried using a ajax method to detect if you close the browser but it is not very reliable. Has anyone had the same problem? I would thank you a lot.
I leave my php and js code to display as I do:
Code JS:
$(function() {
cron(); // Lanzo cron la primera vez
function cron() {
$.ajax({
method: "POST",
url: "closeuser.php",
data: { action: 1 }
})
.done(function(msg) {
var trimmedString = msg.trim();
console.log(trimmedString)
if( trimmedString == 'success' ) { // Valida si el server devolvió 'success'
location.href='logoutuser.php';
}
});
}
setInterval(function() {
cron();
}, 10000); // cada 10 segundos
});
Code PHP:
<?php
require_once 'Connections/sesionunica.php';
$connection_s = new sesionunica();
if(!isset($_SESSION["id_user"])){
echo"<script>location.href='index.php';</script>";
}
if(isset($_POST["action"])) { // Se pasa una acción
switch(sprintf("%d", $_POST["action"])) { // ¿Qué acción?
case 1:
cerrar();
break;
default:
echo "default";
}
}
function cerrar(){
$ses = session_id();
$connection_s = new sesionunica();
$userById = $connection_s->getUsers($_SESSION["id_user"]);
if ($userById["id_sesion"] <> $ses) {
echo "success";
}
}
?>
In the same way, I cannot use websockets since there are accessibility problems with the server.
I think you could create an "access filter" that would check if the "access token" is valid or not in every request the users would make.
If the "access token" is expired, then return an HTTP status 401 (unauthorized), and, in client-side, redirect the user to login page.
Request filter is a very common resource that many REST frameworks have.
I am using Yii framework and I am creating a register page for the user. In order for a user to create an account, they need to enter in a ticket code. A widow form pops up and they fill out the ticket code, it ajax validates it properly and stores it as a session variable. The popup window closes and allows the user to fill out the rest of the form and submit it. The form should then validate the information, create the user, reasign the ticket's user_ID to the new user_ID, and load the page /ticket/mytickets.
what happens, the ticket is confirmed that it exists, saves it into the session, the user is created, the ticket reassign method gets called, the ticket is never reassigned, and the page reloads. When I echo out the page on the reload, it shows the correct information for the user_ID, and the ticket_ID.
Any hints would help for debugging this would be helpful. Thank you
//controler
public function actionRegister()
{
$model=new User;
$valid = false;
//check to see if valid
if(isset($_POST['User'])){
$valid = $model->checkValid();
}
if($valid)
{
$model->attributes=$_POST['User'];
$user_ID = $model->ID;
if($model->save()){
//save ticket to user
$reassigned = Ticket::model()->reassign_with_IDs($_SESSION['ticket_ID'],$user_ID);
if($reassigned){
unset($_SESSION['ticket_ID']);
//redirect to mytickets
$this->redirect(array('/ticket/mytickets'));
}
}
}
$this->render('register',array(
'model'=>$model,
));
}
//model
public static function reassign_with_IDs($ticket_ID,$user_ID){
$ticket = Ticket::model()->findByPK($ticket_ID);
$ticket->user_ID = $user_ID;
if($ticket->save()){
return true;
}
else{
return false;
}
}
$model->ID is only set after $model is saved. Therefore your code should read:
if($valid)
{
$model->attributes=$_POST['User'];
if($model->save()){
//save ticket to user
$user_ID = $model->ID;
$reassigned = Ticket::model()->reassign_with_IDs($_SESSION['ticket_ID'], $user_ID);
You can however get rid of the reassign_with_IDs function and the unnecessary variable user_ID and just explicitly set the ticket using:
$reassigned = Ticket::model()->updateByPk($_SESSION['ticket_ID'], ['user_ID'=>$model->ID]);
I have a javascript variable called "list". I need to send it as a POST data to another page and open that page in a new tab (with the POST data present).
This code:
jQuery.post('datadestination.php', list);
sends the data all right, but ofcourse it opens the page in the same tab.
I saw some solutions to similar problems using invisible form and things like that, but I could not get them to work. Is there any simple solution?
You can send a form using the target="_blank" attribute.
<form action="datadestination.php" method="POST" target="_blank" id="myform">
<input type="hidden" name="list" id="list-data"/>
<input type="submit" value="Submit">
</form>
Then in JS:
jQuery('#list-data').val(list);
jQuery('#myform').submit();
This is an implementation of Sergey's solution.
<?php // this is save.php
session_start();
// DO NOT just copy from _POST to _SESSION,
// as it could allow a malicious user to override security.
// Use a disposable variable key, such as "data" here.
// So even if someone passed _POST[isAdmin]=true, all that he would do
// is populate _SESSION[data][isAuthenticated], which nobody reads,
// not the all-important _SESSION[isAuthenticated] key.
if (array_key_exists('data', $_POST)) {
$_SESSION['data'] = $_POST['data'];
$_SESSION['data.timestamp'] = time();
// Let us let the client know what happened
$msg = 'OK';
} else {
$msg = 'No data was supplied';
}
Header('Content-Type: application/json; charset=utf8');
die(json_encode(array('status' => $msg)));
?>
In the first page:
$.post('save.php', { data: list }, function(response){
if (!response.status) {
alert("Error calling save");
return;
}
if (response.status !== 'OK') {
alert(response.status);
return;
}
// We had a response and it was "OK". We're good.
window.open('datadestination.php');
});
And in datadestination.php add the fix:
if (!array_key_exists('data', $_SESSION)) {
die("Problems? Did you perchance attempt to reload the page and resubmit?");
// For if he did, then yes, $_SESSION would have been cleared.
// Same if he is operating on more than one window or browser tab.
}
// Do something to validate data. For example we can use data.timestamp
// to assure data isn't stale.
$age = time();
if (array_key_exists($ts = 'data.timestamp', $_SESSION)) {
$age -= $_SESSION[$ts];
}
if ($age > 3600) {
die("Data is more than one hour old. Did someone change server time?!?");
// I actually had ${PFY} do that to me using NTP + --hctosys, once.
// My own time zone is (most of the year) exactly one hour past GMT.
}
// This is safe (we move unsecurity-ward):
$_POST = $_SESSION['data'];
unset($_SESSION['data'], $_SESSION['data.timestamp']);
// keep things clean.
// From here on, the script behaves "as if" it got a _POST.
Update
You can actually merge save.php and datadestination.php and use a "saving stub" savepost.php that you can recycle in other pages:
<?php
session_start();
// DO NOT just copy from _POST to _SESSION,
// as it could allow a malicious user to override security.
// Use a disposable variable key, such as "data" here.
if (array_key_exists('data', $_POST)) {
// Timestamp sent by AJAX
if (array_key_exists('ts', $_POST)) {
// TODO: verify ts, but beware of time zones!
$_SESSION['data'] = $_POST['data'];
Header("Content-Type: application/json;charset=UTF-8");
die(json_encode(array('status' => 'OK')));
}
die("Error");
}
// This is safe (we move unsecurity-ward):
$_POST = $_SESSION['data'];
unset($_SESSION['data']); // keep things clean.
?>
Now your call becomes
$.post('datadestination.php', { data: list, ts: Date.now() }, function(){
window.open('datadestination.php');
});
and in your datadestination.php (or anywhere else) you add
require 'savepost.php';
I suggest:
Pass that list with the jquery.post() function and save it in the SESSION array.
Open a new tab with the same file/address/URL with the window.open() function.
Retrieve saved data from the SESSION array.
This seems straightforward and clean to me.
I have a web page that allows users to complete quizzes. These quizzes use JavaScript to populate original questions each time it is run.
Disclaimer: JS Noob alert.
After the questions are completed, the user is given a final score via this function:
function CheckFinished(){
var FB = '';
var AllDone = true;
for (var QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] < 0){
AllDone = false;
}
}
}
if (AllDone == true){
//Report final score and submit if necessary
NewScore();
CalculateOverallScore();
CalculateGrade();
FB = YourScoreIs + ' ' + RealScore + '%. (' + Grade + ')';
if (ShowCorrectFirstTime == true){
var CFT = 0;
for (QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] >= 1){
CFT++;
}
}
}
FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + QsToShow;
}
All the Javascript here is pre-coded so I am trying my best to hack it. I am however struggling to work out how to pass the variable RealScore to a MySql database via PHP.
There are similar questions here on stackoverflow but none seem to help me.
By the looks of it AJAX seems to hold the answer, but how do I implement this into my JS code?
RealScore is only given a value after the quiz is complete, so my question is how do I go about posting this value to php, and beyond to update a field for a particular user in my database on completion of the quiz?
Thank you in advance for any help, and if you require any more info just let me know!
Storing data using AJAX (without JQuery)
What you are trying to do can pose a series of security vulnerabilities, it is important that you research ways to control and catch these if you care about your web application's security. These security flaws are outside the scope of this tutorial.
Requirements:
You will need your MySQL database table to have the fields "username" and "score"
What we are doing is writing two scripts, one in PHP and one in JavaScript (JS). The JS script will define a function that you can use to call the PHP script dynamically, and then react according to it's response.
The PHP script simply attempts to insert data into the database via $_POST.
To send the data to the database via AJAX, you need to call the Ajax() function, and the following is the usage of the funciton:
// JavaScript variable declarations
myUsername = "ReeceComo123";
myScriptLocation = "scripts/ajax.php";
myOutputLocation = getElementById("htmlObject");
// Call the function
Ajax(myOutputLocation, myScriptLocation, myUsername, RealScore);
So, without further ado...
JavaScript file:
/**
* outputLocation - any HTML object that can hold innerHTML (span, div, p)
* PHPScript - the URL of the PHP Ajax script
* username & score - the respective variables
*/
function Ajax(outputLocation, PHPScript, username, score) {
// Define AJAX Request
var ajaxReq = new XMLHttpRequest();
// Define how AJAX handles the response
ajaxReq.onreadystatechange=function(){
if (ajaxReq.readyState==4 && xml.status==200) {
// Send the response to the object outputLocation
document.getElementById(outputLocation).innerHTML = ajaxReq.responseText;
}
};
// Send Data to PHP script
ajaxReq.open("POST",PHPScript,true);
ajaxReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajaxReq.send("username="username);
ajaxReq.send("score="score);
}
PHP file (you will need to fill in the MYSQL login data):
<?php
// MYSQL login data
DEFINE(MYSQL_host, 'localhost');
DEFINE(MYSQL_db, 'myDatabase');
DEFINE(MYSQL_user, 'mySQLuser');
DEFINE(MYSQL_pass, 'password123');
// If data in ajax request exists
if(isset($_POST["username"]) && isset($_POST["score"])) {
// Set data
$myUsername = $_POST["username"];
$myScore = intval($_POST["score"]);
} else
// Or else kill the script
die('Invalid AJAX request.');
// Set up the MySQL connection
$con = mysqli_connect(MYSQL_host,MYSQL_user,MYSQL_pass,MYSQL_db);
// Kill the page if no connection could be made
if (!$con) die('Could not connect: ' . mysqli_error($con));
// Prepare the SQL Query
$sql_query="INSERT INTO ".TABLE_NAME." (username, score)";
$sql_query.="VALUES ($myUsername, $myScore);";
// Run the Query
if(mysqli_query($con,$sql))
echo "Score Saved!"; // Return 0 if true
else
echo "Error Saving Score!"; // Return 1 if false
mysqli_close($con);
?>
I use these function for ajax without JQuery its just a javascript function doesnt work in IE6 or below. call this function with the right parameters and it should work.
//div = the div id where feedback will be displayed via echo.
//url = the location of your php script
//score = your score.
function Ajax(div, URL, score){
var xml = new XMLHttpRequest(); //sets xmlrequest
xml.onreadystatechange=function(){
if (xml.readyState==4 && xml.status==200){
document.getElementById(div).innerHTML=xml.responseText;//sets div
}
};
xml.open("POST",URL,true); //sets php url
xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xml.send("score="score); //sends data via post
}
//Your PHP-script needs this.
$score = $_POST["score"]; //obtains score from POST.
//save your score here
echo "score saved"; //this will be displayed in the div set for feedback.
so call the javascript function with the right inputs, a div id, the url to your php script and the score. Then it will send the data to the back end, and you can send back some feedback to the user via echo.
Call simple a Script with the parameter score.
"savescore.php?score=" + RealScore
in PHP Side you save it
$score = isset ($_GET['score']) ? (int)$_GET['score'] : 0;
$db->Query('INSERT INTO ... ' . $score . ' ...');
You could call the URL via Ajax or hidden Iframe.
Example for Ajax
var request = $.ajax({
url: "/savescore.php?score=" + RealScore,
type: "GET"
});
request.done(function(msg) {
alert("Save successfull");
});
request.fail(function(jqXHR, textStatus) {
alert("Error on Saving");
});
I'm trying to create a sort of mail on my site.
So I have a table that contains three columns, let's say (for simplicity , but in reality) , with the two int fields ( from, to ) and a timestamp (date of sending )
a part of my page , I display a list of messages with a group by to to group all messages that are destined for the same person .
Eventually I want to display the entire conversation when clicking on the message but it is not obvious.
I tried jquery ajax and then an iframe but it is not great , because on one hand it does not return me anything (white pages) and secondly the reload each second is not great .
At first I would like to display the result of my request.
I have not set callback because I do not know what to do with an application in a jquery callback . I thought the easiest way was to do my processing in php and run my loop then displays everything in the iframe .
So I put it in jquery
$( ".load_message" ).click(function() {
//On marque uniquement l'id de l'expediteur et du destinataire
// pour chercher les messages expédiés par A vers B ou inversement
var from = $(this).closest('tr').find('span.from').text();
var to = $(this).closest('tr').find('span.to').text();
$.ajax({
type: 'POST',
url: 'pages_ajax/fetch-messages.php',
data: { from: from, to: to},
dataType: "json"
});
});
setInterval(refreshIframe1, 1000);
function refreshIframe1() {
$("#messages")[0].src = $("#messages")[0].src;
}
and the php page I have this:
<?php
session_start();
require_once("../../lib_php/librairie.php");
require_once("../../config/connexion.php");
//header('Content-Type: application/json; charset=utf8');
/**
* Fonction qui retourne une liste de messages
* #return int
*/
function fetchMessages() {
if (isset($_POST['from'])) {
$from = mysql_real_escape_string($_POST['from']);
$to = mysql_real_escape_string($_POST['to']);
$query = "SELECT `id`, `from`, `to`, `message`, `sent`, `read`, `direction`
FROM `cometchat`
WHERE `from` = {$from} || `from` = {$to} || `to` = {$to} || `to` = {$from}";
return $query;
} else {
return null;
}
}
if (isset($_POST['from'])) {
$liste_messages = fetchMessages();
if (!is_null($liste_messages)) {
$result_message = mysql_query($liste_messages);
while ($mess = mysql_fetch_assoc($result_message)):
?>
ici
<?php
endwhile;
}
}
?>
But for now nothing works I do not even have my messages while running the echo of my query in phpMyAdmin return me something. I guess I'm loosing context when reloading ($_POST are loosing themselves)
I would initially display the entire conversation in an iframe or a div, then after whatever it is automatically updated if ever there's new posts in the meantime a bit like the messaging system on Facebook with no reloading of the page.
Any help will be greatly appreciated.
it's been a while you asked the question hope u solved it. Anyway is what i can tell from your code and what you try to do:
Your jquery function have no callback (success, complete)
Your php code don't return anything, you just do a loop like you want to manipulate each record, and reading your post you want to have your ajax to read all value in a success callback... So don't need a loop except you want to parse it, just expose them with json_encode($mess);
setInterval 1s? argh!!! Will your server handle it? Use something like 10 à 30s or 4:
go for websocket solution like racket in php or use nodejs plateform (nodejs + socket.io + redis)
Hope it helped you out or someone else