Setting up a delay notification with php - javascript

I need to write a php function for sending a Telegram notification after 4 hours.
With the application i'm posting data into a SQL db, after I pressed the Submit button, i need that a php function starts and after 2 days sends to my Telegram channel a notification, with some of the data that i've posted into the db record.
For the posting part and Telegram part i'm ok, i've already linked the website to the channel and normal notifications from php work fine, but i need some advice on the "reminder" part.
I was thinking about some date() function and post the value in to the record, make another var with the date + 2days e make some for or while cycle but i don't think that this can works. Some advice?
I'm new to php, maybe i dont know some function that could help me?

Add to your table a column and name it notification_send and give it a default value of 0
Create a crontab that calls a php file for example:
*/60 * * * * php -f /etc/www/my_notification.php : calls the file every 60 mintues
In this file create a query that selects all the data with the notification_send = 0 then check if the current_date - date column of each row => 2 days :
If so : update the notification_send value to 1 and send your notification

As I commented, your approach is right. As you asked something more, though, I chose to write an answer.
As you asked, when you send a Telegram notification you have to send a reminder notification after 2 days (48h). If I'm right it's an e-mail.
First of all, as you said, you have to create a column to warn when the remember should be send.
Also, to know if the reminder has been sent or not you have to create another column. It could be a flag (true/false) or a datetime column (null = not sent, filled = sent).
Besides that, a cronjob or schedule have to call a PHP script. I'll show to you an example of a PHP script.
I'll call the table as reminder and the column sendIn and isSent.
//select only the reminder that has the sendIn lesser than now and that not has been sent
$statement = $pdo->query("SELECT * FROM reminder WHERE sendIn <= NOW() AND isSent is null");
//prepared statement to update the reminder sent
$updateStatement = $pdo->query("UPDATE reminder SET isSent = NOW() WHERE id = :id");
foreach($statement as $reminder)
{
/**
script to send the reminder
**/
//update the reminder
$updateStatement->execute(array(':id' , $reminder['id']));
}
To create a cronjob, you could take a look here:
https://askubuntu.com/questions/2368/how-do-i-set-up-a-cron-job
You don't need to delete the cron, just let it run periodically and send all your reminders.

Related

how to show user's “last seen at” time using the seconds received from the server

i want to display when a user last seen online by time like whatsapp
using xmpp and angular
i made an xmpp request and i get user last seen by second and i want to convert it to time
what i got :
user last seen 903 seconds ago
what i want :
user last seen at 11:30 pm
Last Activity Response by Server¶
<iq from='juliet#capulet.com'
id='last1'
to='romeo#montague.net/orchard'
type='result'>
<query xmlns='jabber:iq:last' seconds='903'>Heading Home</query>
</iq>
If you take the seconds value you received from server to a variable, you can do it like below.
const timeInSeconds = getValueFromServer();
const lastLoggedInTime = new Date(Date.now() - timeInSeconds * 1000);
In your html template, you can use lastLoggedInTime variable to show the date.

Show same content at same time in different browser

I am developing a numbers game where users will buy numbers and after 2 days winners will be drawn.
I am using PHP for the backend and jQuery for the frontend.
My problem is when drawing occurred user on different browser can't see same numbers, these draw numbers are being generated by PHP.
I was thinking maybe I can build these game by PHP and Javascript but it looks not easy. Can you guys please suggest some alternative? How can I improve this code to show the same number on the different browser?
I have the idea that it is not possible to generate a random number for each request. Maybe I can save the number in the database and then get this number in PHP such that the number will be unique for each request.
The actual issue is to create the same content for each user in different browsers. Any help would be really appreciated.
Javascript:
var myTimer = setInterval(checkDrawDate, 1000);
function checkDrawDate() {
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
var x = new Date(dateTime);
var y = new Date("{{$drawDate}}"); //this is laravel variable which contain drawdate e.g. 2017-07-05
if(x >= y){
drawNumber();
}
}
function drawNumber(){
$.get("{{ route('ajaxcomparepowerball') }}",{'gameId': gameid}, function(res){
$('#mybets').html(res.html);
});
}
PHP:
public function ajaxDrawNumber(Request $req){
return rand(0,49);
}
A Cron Job will be needed to implement this functionality. As you are drawing a number on particular time (after $drawDate in your case). So the cron job will execute once in day, check whether $drawDate for each game is today or passed. If condition true, $drawDate <= now, call a function to generate random draw number rand(0,49) and save it to database corresponding to gameid of matched games(having $drawDate <= now).
By doing this, a lot Javascript work will be reduced. In JS, then need to hit an ajax request with gameid to fetch record having draw number for particular game from database. If record not found, it means random number not drawn yet.
I think you are using Laravel, so to schedule tasks in laravel visit here.
Here some possible solutions.
If you need the same data modified for users in real time I think the best option is WebRTC, quick start here. And here a simple example sending strings in real time between clients.
If you also need interaction server to client you could use server-sent events.
You could perform a bidirectional communication between browser and a server using WebSockets. You can send and receive event-driven responses. Using a database you could communicate two clients.
The easiest is using a database to store the information and perform ajax to send data to the server (and database) and server-sent events to send data to the clients.
Basic Server-sent event example:
Javacript:
var evtSource = new EventSource("myserver.php");
evtSource.onmessage = function(e) {
// listening for new messages here
alert(e.data)// e.data is mynumber
}
Php (myserver.php)
<?php
header('Cache-Control: no-cache');
header("Content-Type: text/event-stream\n\n");
while (1) {
//perform a query in your database with your driver
$result = mysql_query("SELECT mynumber FROM mytable WHERE user = 1");
$row = mysql_fetch_assoc($result);
echo $row['mynumber'];//<-- sending mynumber to client
ob_end_flush();
flush();
sleep(1);// <-- this is every second, but you could fire this with ajax or some other event.
}
This code send a number from server to a client that is listening. If a user made a change, one possibility is that client send an ajax to update some value in the database. So, at the same time, the ajax server could send this as an update to clients listening. In that way the whole process is completed.
I think all you need is this. Call a function in every, say 5 seconds or less and fetch data from server and update it in the page.
window.setInterval(function(){
updateNumber();
}, 5000);// set for every five seconds
function updateNumber(){
//ajax code to fetch live data and append the data in the numbers container
}
And dont forget to cross check the data before saving the numbers in the server.
Hope it helps.!!!
To save and maintain users state, key value store like Aerospike can be used. It is very easy to save and retrieve data in key value store. In above case we just have to generate a unique key using gameId, userId and date. And save user's data against the unique key.
To get started with Aerospike php client following is Aerospike php client
If data is present against the unique id for that particular user just return it, else create the new random number save it against the unique key and return it. Please be careful while creating unique key. Instead of using server side date-time please send date in ajax call request so there will not be any issue with time zone. It will be always user's timezone and there will not be any issue if server is in different timezone and user is in different timezone.
function drawNumber(){
$.get("{{ route('ajaxcomparepowerball') }}",{'gameId': gameid,'date':user-timezone-date}, function(res){
$('#mybets').html(res.html);
});
}
Here "user-timezone-date" should be fix date format like 'MM-dd-yy' which will indicate the same day. hours or seconds should not be included while generating unique key otherwise at the time of retrieving the user's state; generating particular unique will be changed every hour or every second and whole purpose of of doing this will be shattered.
I am new to StackOverFlow so I am not able to comment on the answers. In case of corn job as well we have to be careful with time-zones if server and users are in different time zones. Otherwise user's will see different random number before user's day is complete. Please improve answer by commenting on it and suggestions are always welcome.

How to customize a dynamic website in PHP and JS?

I am working on a website to analyse energy data that I get from several remote meters. I'm using JS, PHP and mySQL. I developed the website with one client's data (specific type and numbers of remote meters). This is the first website I did, I have a lot to learn.
There are the steps:
Login form // same for everyone
PHP check login // same for everyone
Index page // same for everyone
Javascript with AJAX function to post data (range of date) to a php file (calculation.php) to calculate stuff // JS file is the same for everyone
PHP file gets the data from mySQL and does many calculation about energy stuff, then echoes it
The JS file gets the data (via AJAX) and then displays graphs via google Chart library
The problem is that the PHP file that gets the AJAX POST (end of step 4 and step 5) won't do the same calculation for every client. So I don't know what to do, I'm a bit lost.
I thought at:
Putting a condition in the PHP file for every client, like "if
client_id=X" // this seems too bad with dozens of clients
Writing a different PHP file for every client. Writing the name of
this PHP file in the mysql table "clients". Doing an intermediate php
file called by AJAX that will check the client_id against the
database then "include" the specific PHP file into the temporary one.
Writing the PHP PDO request in a string type into the table
"clients" then query it from the PHP file "calculation.php". The PHP file will do the correct command.
These solutions don't seem good to me (maybe the third?). Do you have any idea? Thank you in advance.
EDIT Example of php code
first client:
$reponse1 = $bdd->prepare("SELECT DATE_FORMAT(Date, '%H:%i') AS timekey, AVG(Value) FROM meter1 WHERE Date>='$from' AND Date<='$to' GROUP BY timekey");
$reponse1->execute();
$myArrayLP24temp1['Hour']= $reponse1->fetchAll(PDO::FETCH_COLUMN, 0);
$reponse1->execute();
$myArrayLP24temp1['Value']= $reponse1->fetchAll(PDO::FETCH_COLUMN, 1);
$reponse2 = $bdd->prepare("SELECT DATE_FORMAT(Date, '%H:%i')AS timekey, AVG(Value) FROM meter2 WHERE Date>='$from' AND Date<='$to' GROUP BY timekey");
$reponse2->execute();
$myArrayLP24temp2['Value']= $reponse2->fetchAll(PDO::FETCH_COLUMN, 1);
for ($ii=0; $ii<24*4; ++$ii){
$meter1NoRound=$myArrayLP24temp1['Value'][$ii]*4;
$meter2NoRound=$myArrayLP24temp2['Value'][$ii]*4;
$meter1=round($meter1NoRound,1);
$meter2=round($meter2NoRound,1);
$myArrayLP24['rows'][]= array('c' => array( array('v'=>$myArrayLP24temp1['Hour'][$ii]), array('v'=>($meter1)), array('v'=>($meter2))));
second client:
$reponse1 = $bdd->prepare("SELECT DATE_FORMAT(Date, '%H:%i') AS timekey, AVG(Value) FROM meter1 WHERE Date>='$from' AND Date<='$to' GROUP BY timekey");
$reponse1->execute();
$myArrayLP24temp1['Hour']= $reponse1->fetchAll(PDO::FETCH_COLUMN, 0);
$reponse1->execute();
$myArrayLP24temp1['Value']= $reponse1->fetchAll(PDO::FETCH_COLUMN, 1);
for ($ii=0; $ii<24*4; ++$ii){
$meter1NoRound=$myArrayLP24temp1['Value'][$ii]*4;
$meter1=round($meter1NoRound,1);
$myArrayLP24['rows'][]= array('c' => array( array('v'=>$myArrayLP24temp1['Hour'][$ii]), array('v'=>($meter1))));
The examples above show two differents code. The first one is for a client with two meters, the second one for a client with one meter. It can be up to 10 meters, and sometimes there will be sub meters that I will have to add up sometimes not. So the code is different for every client (except for clients with the exact same configuration, but that won't happen very often).
Why not storing the variable values in data base ?
Then, when client comes you have all the require infos to make your calculation.
Think simple and standardize the more you can.
Never forget that a good developer is a lazy person ;-)
EDIT
When you're saying :
"The problem is that the PHP file that gets the AJAX POST (end of step 4 and step 5) won't do the same calculation for every client."
What do you mean ?
The calculation formula is different for each client ?
The values to use in the formula are different for each client ?
The way i understood your question is in the first case.
Whatever, for both cases, store what you need in DB and use it as it comes with the client.
May be i didn't understand well what you need. If it is, please, send a piece of code to illustrate your problem.

How to delete mysql data from table at midnight?

I have a mysql table and I want it to be "emptied" every night at midnight. I have searched for an answer on the web and came across nothing that seemed to help me. I had this idea of using javascript to get the current time and then run an if statement and see if it is equal to midnight and if it was to execute a php script that deleted the information.
Javascript:
var myVar=setInterval(function(){myTimer()},1000);
function myTimer()
{
var d=new Date();
var t=d.toLocaleTimeString();
if(t == 12:00:00 AM){
$.ajax({
URL: 'delete.php';
});
};
};
delete.php:
<?php
require 'connect.php';
mysql_query("DELETE * FROM messages;");
?>
I have tested this by setting the time in the if statement to a time a few minutes ahead of my actual time and it does not work.
Implementing your own event scheduler, especially as a web page using JavaScript is a bad idea.
Use for that either
a cron job to run DELETE statement through the mysql command line interface
/path/to/mysql -u<user> -p"<password>" <db_name> -e "delete from messages"
or a MySQL event, e.g.
CREATE EVENT delete_messages_at_midnight 
ON SCHEDULE EVERY 1 DAY STARTS CURDATE() + INTERVAL 1 DAY
DO DELETE FROM messages;
If you go with MySQL event approach:
use SHOW PROCESSLIST to check if the event scheduler is enabled. If it's ON you should see a process "Daemon" by user "event_scheduler".
use SET GLOBAL event_scheduler = ON;to enable the scheduler if it's currently not enabled.
More on configuring event scheduler read here

check if JSON data has changed and alert rows

I am trying to develope a app that checks MYSQL table every minute for new messages and if there is any it should alert the user and show the message. This is the code I use, how should I modify it to make it work?
setInterval ( "getMessages()", 60000 );
var oldmessage = "";
function getMessages() {
$.getJSON(serviceURL + 'messages.php?ID=' + ID, function(message) {
if(JSON.stringify(message) != JSON.stringify(oldmessage)){ // old message is not same as new
var messages = data.key[0];
alert(messages.NEW);
});
oldmessage = message;
}
So what I'm trying to do is save old message to variable and compare it after minute, and if it has changed I alert row NEW
The possible solution is, you take a new column in mysql to mark as viewed or not. By default that will be not viewed (say 0). In your PHP code you should retrieve one row which is marked as "Not viewed" or 0. And same you should display via AJAX and update back that row with 1 (viewed).
If you dont receive any rows, send nothing to AJAX and handle the messages accordingly no new rows found.
This is just a logic and hope it helps.

Categories

Resources