I have a database which when inserted into should create a notification in the webpage. What I did here was polling through ajax. I execute a query which selects for a row whose timestamp is less than 3 seconds from current time.
Here is my code-
HTML file:
<html>
<head>
<title>Dashboard</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3 /jquery.min.js"></script>
</head>
<body>
<div id="responsecontainer"></div>
<script type="text/javascript">
$( document ).ready(function() {
setInterval(ajaxcall, 500);
function ajaxcall() {
$.ajax({
type: "GET",
url: "maintdashsubmit.php",
dataType: "html", //expect html to be returned
success: function(response){
$("#responsecontainer").append(response);
}
});}
});
</script>
</body>
</html>
PHP file:
<?php
session_start();
$link = mysqli_connect("localhost", "root", "*****", "DMRC");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "SELECT * FROM Ticket, Station, user_auth WHERE TIME(ticket_open_datetime) BETWEEN curtime()-3 AND curtime() AND Ticket.ticket_station_id = Station.station_id AND Ticket.ticket_open_emp_id = user_auth.emp_id AND Ticket.ticket_close_open='open" ;
$result = $link->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()){
echo "<tr><td style='width:15%''>".$row['ticket_id']."</td><td><table><tr><td>".$row['ticket_equipment']."</td></tr><tr><td>".$row['ticket_equipment_id']."</td></tr></table></td><td>".$row['station_name']."</td><td><table><tr><td>".$row['emp_firstname']." ".$row['emp_lastname']."</td></tr><tr><td> Sec:".$row['emp_section']."</td></tr><tr><td>".$row['emp_id']."</td></tr></table></td><td>".$row['ticket_close_open']."</td></tr>";
}
}
$link->close();
?>
This gives me the most recent notification that I want to see. But it displays multiple times as long as it remains within the 0.5 seconds time limit.
I read that I can keep a column in the database that can be set 1 if the notification has been displayed and 0 if not.
But I have a doubt. Suppose this notification has to be received by many users. What if displaying a notification to one user sets the column entry 1 before it was viewed by another? This is all so confusing. If anyone can suggest a way?
What if displaying a notification to one user sets the column entry 1 before it was viewed by another?
It sounds like what you're looking for is called a "many to many" relationship. Suppose you have tables for Users and Notifications:
Users
----------
ID
Username
etc.
Notifications
----------
ID
MessageBody
etc.
If each notification can be seen by many users, and each user can see many notifications, and you want to track some piece of information about that interaction (whether a user has seen a notification), then you want a linking table between them. Something like this:
UserNotifications
----------
UserID
NotificationID
HasBeenSeen
etc.
(You can give this table its own ID, or you can use the combination of UserID and NotificationID as a compound primary key. Either way is valid, it's up to you.)
With a many-to-many relationship you need to have such a "linking table" between the two entities which are related. In that table you'd track information about the relationship itself, which in this case would include whether the user has seen the notification.
If you expect this table to grow significantly over time, there are a variety of things you can do to modify the approach slightly. For example, do you need to permanently retain the history of these things? Maybe delete records after they've been viewed? Do notifications themselves get deleted? If so, you would also delete these linking records along with them. Or perhaps the table doesn't store whether a user has seen a notification, but instead stores the notifications a user still needs to see. Then as it's seen, the record is deleted.
There are a variety of approaches you can take to solve the overall problem. But to address the specific question asked here, what you need to track the information is a many-to-many linking table.
Related
This is my php code that will put the inserted data to database and will prevent to insert data if there is duplicate.
include('session.php');
$cid="";
$chat_name=$_POST['chatname'];
$chat_password=$_POST['chatpass'];
$sql3="SELECT * FROM chatroom where chat_name='$chat_name'";
$query=mysqli_query($conn,$sql3);
if(mysqli_affected_rows($query) == 1){
echo("<script>alert('ee');</script>");
}
else{
mysqli_query($conn,"insert into chatroom (chat_name, chat_password, date_created, userid) values ('$chat_name', '$chat_password', NOW(), '".$_SESSION['id']."')");
$cid=mysqli_insert_id($conn);
mysqli_query($conn,"insert into chat_member (chatroomid, userid) values ('$cid', '".$_SESSION['id']."')");
echo $cid;
}
this is jquery code
$(document).on('click', '#addchatroom', function(){
chatname=$('#chat_name').val();
chatpass=$('#chat_password').val();
$.ajax({
url:"add_chatroom.php",
method:"POST",
data:{
chatname: chatname,
chatpass: chatpass,
},
success:function(data){
window.location.href='chat.php';
}
});
});
When I enter a duplicate data the alert in echo don't execute but it continue to put in database although it is duplicate. THANKS FOR THE HELP !
First thing, I would change
if(mysqli_affected_rows($query) == 1){
to
if(mysqli_affected_rows($query) >= 1){
this will make sure that even if there are already duplicates, no more duplicates can be added
There are however some bigger issues with the code that you should address
You should add a uniqueness constraint on your chatname (in the database). This will make it that even if your code is wrong, you will not be able to add duplicate entries to your table.
You are receiving user input and just adding it into your sql querys. This leaves your database open to SQL injection which basically means, anyone can do anything to your database (delete things, add things, etc.). You should look into prepared statements to solve this issue
So i know some html, css, js, php and mysql but my knowledge is very limited regarding security issues
and for a website i'm building till now i just used css display:none (triggered with js) to
show or not to show some content to the user depending on his type (client, employee, boss).
I've understood that if you don't want to have the risk of someone seeing something he should
not (inspect page or some other way) you should not send that information(from server-side = php) at all.
I'm not sure if the way i have in mind is the right one.
If i have 3 types of users 1)clients 2)employees 3)Boss
and i want to show different content (basically the same content but a bit more information
to employees and even more to boss) to each of them for 5 of the pages that exist in the website would it be effective
to have 3 different php files(one for each type of user) for each page , store at $_SESSION['authority'] different values for each user during the login process and use that value to decide which page he can access?
For example the starting page is index.php and when the user logs in depending on his authority level (retrieved from database) he will be
redirected by using header("Location: name_of_page.php"); to index.php if he is a client, to index_employee.php if he is an employee
and to index_boss.php if he is the boss.
And in each of these pages use something like the following to prevent users with different authority to enter.
index_boss.php
<?php
session_start();
if($_SESSION['authority'] == 2 && $_SESSION['loggedin'] == true) {
?>
page content
<?php
}
else
{
if( $_SESSION['authority'] == 1 )
{
header("Location: index_employee.php");
}
else
{
header("Location: index.php");
}
}
?>
Is this the correct way to tackle this issue?
Are there ways to just use 1 php file for all users and hide or show some of the content with some other secure way?
YES it possible in the same page to do this! Just do tit like this:
according to: 1)Boss 2)employees 3)clients
index.php
<html>// Start the session here
<?php session_start();?>
<head>
//Your configuration
</head>
<body>
<?php
if($_SESSION['authority'] == 1 && $_SESSION['loggedin'] == true) {
?>
Here the Contents of the boss
<?php
elseif($_SESSION['authority'] == 2 && $_SESSION['loggedin'] == true) {
;?>
Here the contents of employee
<?php }else{ ?>
Here the contents of clients
<?php };?>
</body>
</html>
The appropriate solution here is a role based system. In other words, create 3 roles and put users into those roles. The objects you will need are:
User
Role
Permission
Optionally - application
Optionally - part of an application (action for example)
Create your role based permissions system using these objects. Hope that helps!
Your implementation does seem correct for a low level site. However, as you scale it might be difficult to keep track of these for every single part or sub-part of your website.
I would suggest either using a class approach (create a different class for each user and use objects) or even use a framework which would usually encompass usage of classes within its own structure to ease the process of implementation and coding from your side.
Frameworks you might like to implement include CodeIgniter or Laravel (in no particular order) - bear in mind that at the moment, your code is doing these if checks every single reload - a correctly implemented class or framework would in most cases automatically know what to do giving a slightly quicker reaction time but more importantly, a clearer code structure and a good base to develop on.
I'm opening a new thread here for more clarity, since we solved the first problems, thanks to you guys :)
We have an AI which is constantly writing a text and pushing it into a MySQL bdd. We want to show this text as an infinite publishing thing online. We would like to see it writing, like when you're on your screen and you're writing a text so we tried this :
<!DOCTYPE html>
<head>
<script type = "text/javascript" src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="myTable"></div>
<script type="text/javascript">
function page_refresh() {
$.ajax({
url : 'getData.php',
type : 'GET',
success : function(data) {
$('#myTable').html(data);
},
error : function(request,error)
{
alert("Request error : "+JSON.stringify(request));
}
});
}
var period = 100; //NOTE: period is passed in milliseconds
setInterval(page_refresh, period);
</script>
</body>
And for getData.php
<?php
$dbhandle = new PDO("mysql:host=localhost;dbname=writing", "root", "*********");//this connects to your mysql table
$sql = "SELECT text, id, date FROM table_02 ;"; //thise is your query, where you select what data you want from the table
$query = $dbhandle->prepare($sql);
if ($query->execute() == FALSE)
{ die("Query error: " . implode($query->errorInfo(), ' ')); } //this is a measure to close the connection if there is an error
echo('<table>');
echo('<tr><th>Test</th></tr>');
while ($row = $query->fetch()) {
echo('<tr>');
##echo('<td>'.$row ['id'].'</td>');
##echo('<td>'.$row ['date'].'</td>');
echo('<td>'.$row ['text'].'</td>');
echo('</tr>');
}
echo('</table>');
?>
The
var period = 100; //NOTE: period is passed in milliseconds
setInterval(page_refresh, period);
seems to not work well with such low timings, it look like it's just refreshing the whole page with the test datas we have. Plus, for some reasons, the page remains blank for a few seconds before showing the datas. Is there a more interesting way to do this ?
Do you have any knowledge of using WebSockets ? This technology was created to replace periodical polling of the server to get updates. Instead of polling from client, server can push changes to the client. You can read more about it here
As I said in my comment, 100ms won't do for your database to fetch the data for the webservice and for the webservice to relay the data to your frontend. This will only work properly if you're working with low quantities of data and if your webservice server resides on the same machine (or close to it) of your database server.
Now, for the "more interesting way of doing this".
You could fetch the data you need every 100ms, no problem, but you can't try to display it right away (I already explained why in my comment). Instead, build a queue and a function to display the first element of it. When the function returns, it's time to pop the first element off the queue and display the next one. This way you ensure that text will always be displayed correctly and in order of insertion.
I am needing a little help with updating a mysql table from data in an jquery array using ajax. I have tried searching for similar issues but could not find anything, or maybe I do not know the correct terms to search... I'm still fairly new to web dev/coding.
I'll try explain what I am trying to do as clearly as I can. I have a page with seats which users select by clicking on them, upon clicking the seat ID is added in its own span tag in a kind of shopping cart area on the left of the page. This works fine.
Upon checkout my js file is able to pick up these seat ID's in an array, but from here I am unsure of how to properly send this array to the php file, and then for the php file to read the seat ID's from the array and update the relevant seat rows to change the availability from 1 to 0 (this is using ajax).
Here is my code:
checkout.js
$(document).ready(function(){
$('#checkout').click(function(){
var status = sessionStorage.getItem("username");
if(sessionStorage.getItem("username")){
var tickets = [];
$("#myTickets").find("span").each(function(){ tickets.push(this.id); });
var type = "POST",
url = "scripts/sendSeatDetails.php";
console.log(tickets);
$.ajax ({
url:url,
type:type,
data:tickets,
success: function(response){
if(response == 5){
alert("Seat update query failed");
} else {
alert("success");
}
}
});
} else {
alert("Before purchasing please log in. If you do not have an account please register.");
}
});
});
In the console log this shows: ["A2", "A3", "A4"] (if I have selected seats with ID A2, A3, A4 etc).
sendSeatDetails.php
<?php
include("dbconnect.php");
$myseats=$_POST['tickets'];
$query="update seats set status='0' where seatnum=";
for($i=0;$i<count($myseats);$i++){
$query.="'$myseats[$i]'";
if($i<count($myseats)-1){
$query.=" || seatnum=";
}
}
$link = mysql_query($query);
if (!$link) {
echo 5;
}
?>
This returns the alert showing success, but this is not true as the tables are not being updated. Can anyone help me with this or point me in the right direction?
I appreciate your help, and hopefully will be able to contribute to this site when I am at a better skill level in the future.
Many Thanks.
To send an array in jQuery you have to serialize it then parse it in the PHP file:
data: tickets.serialize(),
...
parse_str($_POST['data'], $data);
And then you treat it as an ordinary array.
Run update query one by one.
$myseats=$_POST['tickets'];
$flag=0;// Total successful updates
$myseats=explode(',',$myseats);
for($i=0;$i<count($myseats);$i++){
$query="update seats set status=0 where seatnum='".$myseats[$i]."'";
$link = mysql_query($query);
if (!$link) {
$flag=$flag+1;
}
}
echo $flag;die;
Check response. it will be number of updated rows.
I have a large database of 10,000 addresses and 5,000 people.
I want to let users search the database for either an address or a user. I'd like to use Twitter's typeahead to suggest results as they enter text.
See the NBA example here: http://twitter.github.io/typeahead.js/examples.
I understand that prefetching 15,000 items would not be optimal from a speed and load standpoint. What would be a better way to try and achieve this?
Since no one made any answer, I will go ahead with my suggestion then.
I think the best fit for your big database is using remote with typeahead.js. Quick example:
$('#user-search').typeahead({
name: 'user-search',
remote: '/search.php?query=%QUERY' // you can change anything but %QUERY
});
What it does is when you type characters in the input#user-search it will send AJAX request to the page search.php with query as the content of the input.
On search.php you can catch this query and look it up in your DB:
$query = $_GET['query'].'%'; // add % for LIKE query later
// do query
$stmt = $dbh->prepare('SELECT username FROM users WHERE username LIKE = :query');
$stmt->bindParam(':query', $query, PDO::PARAM_STR);
$stmt->execute();
// populate results
$results = array();
foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $row) {
$results[] = $row;
}
// and return to typeahead
return json_encode($results);
Of course since your DB is quite big, you should optimize your SQL query to query faster, maybe cache the result, etc.
On the typeahead side, to reduce load to query DB, you can specify minLength or limit:
$('#user-search').typeahead({
name: 'user-search',
remote: '/search.php?query=%QUERY',
minLength: 3, // send AJAX request only after user type in at least 3 characters
limit: 10 // limit to show only 10 results
});
So it doesn't really matter how big your DB is, this approach should work nicely.
This is an example in PHP but of course it should be the same for whatever backend you have. Hope you get the basic idea.