Dynamic end date for countdown - php

Im currently trying to sort out a system on my website (with limited coding experience) that doesnt have many references out there, it would seem.
I currently have paypal IPN integration (untested), that i then use to update the database to give the user "time" on their account. i also have a "stop/start" function in their account that allows them to stop and start their time, with the idea being when they "start" their time will start to count down. conversely, whilst they are "stopped", their countdown will not count down. i guess its similar to pausing an active subscription, but mine is over a short term period.
mysql_query("UPDATE `table` SET
`user_id`=$user_id,
`timeadded`=$timeadded,
`amountpaid`=$mc_gross,
`token`=$txnId,
`currtime`=TIMESTAMP()");
^ that is the snippet i am using to update the mysql table.
$new_time = date('H:i', strtotime('+$timeadded'));
this is what im currently working with to allow me to calculate an end date WITHOUT the start/stop feature i mentioned above. im unsure as to how to proceed from here to integrate that feature though, as obviously the end date would need to be dynamically changing based around other variables than the currentdate.
Ive also referenced this which i think might lead me along the correct track but ive been unsuccessful as of yet.
//time when start clicked
$first = new DateTime
//time when stop clicked
$second = new DateTime
//when start is clicked
exec(mysql_query("UPDATE `newtable` SET `userid`=$userid, `start`= $first"));
//when stop is clicked
exec(mysql_query("UPDATE `newtable` SET `userid`=$userid, `end`= $second"));
//use array to select all entries from newtable where userid=$userid (can fill this in if wanted).
$elapsed = $first->diff( $second );
$timeleft = (strtotime($timeadded) - strtotime($elapsed));
$updateelapsed = mysql_query("UPDATE `newtable` SET `userid`=$userid, `elapsed`=$elapsed")
$allelapsed = mysql_query("SELECT * FROM newtable WHERE userid=$user_id");
$allelapsedarray = mysql_fetch_array($allelapsed);
$timeelapsed = array_sum($allelapsedarray);
//so now i have my total time spent "started", i should be able to compare that to the amount of time they bought. if its more than that, they are rejected, otherwise can continue as normal.
so thats what i have thus far for the start/stop feature to be included. this was just done on the fly after coming across the second link i gave above, and i feel its a more fruitful way of going forward than the potential method i mentioned in the first few paragraphs.
to the below comment - it wont update my database with regards to the start/stop time, nor the elapsed time column. given those things it wont bar people from accessing those areas that need "time", but i assume that that will fix itself when the above is sorted. this method ive developed also seems long winded so i might be overlooking a far simpler way of coding this semmingly straightforward task. thanks in advance for any tips.

Related

Getting data from MySQL for every day of the week

I need to get stats from my site for every day of the week example.
$str_sqlQuery = 'SELECT COUNT(DISTINCT (CASE WHEN (orders.status_id = 1
AND DAYOFWEEK(orders.datetime_ordered) = 1) THEN orders.id
ELSE NULL END)) AS cnt_items_bought_sunday';
I am getting the count for every order made on a sunday where it was successfull. Would it be better to get the orders to PHP and count them there or continue it like this.
I am trying it like this but it seems a little too resource intensive for my server.
First of all check your table was properly made (primary key and indexes used in the correct way, following standards), if it's not, fix that, thanks to that tiny standards you can get a great change in performance.
advice: Let the client (PhP) do the operative part(counting in this case, but operations in general)so you evade the memory hungry part from you sql query execution.
Hope this helps.
Good luck!

Mysql checking for avaliable time between opening times

I am desperate, I read many posts but couldn't quite find a solution...
I have a table called reservations.
In there I have 5 fields
ID(int)
room(TEXT)
date(DATE)
from(TIME)
to(TIME)
lets say in PHP I have 4 variables:
$room = "sauna";
$date = "2015-03-03";
$open_from = "09:00:00";
$open_to = "15:00:00";
I don't know how to make this Query which tells me whether there is still time for use between the opening times or not
I read many threads but I couldn't find anything which has this exact thing.
All I need is a '0' or '1' as a return value so I can simply dynamically remove the "add reservation" button from the page if there's no time left where one could put in a reservation anyways...
Please help me :(
Sincerely
Depth

How to set up drip email system for PHP app

My web app is using CakePHP 2.4 and I'm planning to build a "drip" email feature to deliver follow-up emails over time. This is a very common feature in modern websites, but I'm surprised by how little resources I'm able to find.
My question: Are there any established patterns for doing this? I have some ideas for how to do it but I don't want to reinvent the wheel.
(I did a quick search and I came up empty.)
Note: I'm aware of services like MailChimp which will do this, but my "drips" need to be done dynamically because they are linked to user actions which may or may not have already taken place. For example: I want to send an email every 3 days if a user has not completed their profile. Once they do, they should STOP getting the drips.
Right as requested.
Basically its more of a logic/workflow issue than anything else.
In your case you want to warn a user after 3 days and every 3 days thereafter that their profile isn't complete.
So first up you need some way of detecting that their profile isn't complete in this case I'll use a flag field IsComplete 0/1. By default its 0 (not complete). We also want to know a date that the user signed up so we'll use a simple mysql timestamp field populated with a mysql date in the format yyyy-mm-dd H:i:s, We also want to know a date the user was last email notified. For this we'll use another mysql field this time a datetime field in the same format yyyy-mm-dd H:i:s.
So our user db now looks something like this (note mysql syntax isn't correct)
IsComplete TINYINT 1 DEFAULT 0,
SignupDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
LastWarnDate DATETIME DEFAULT NULL
The NULL on the last warn date is important!
On your front end user profile edit/update page you'll simply add the following into the save bit
if (PSEUDO_CODE_ALL_FIELDS_ARE_COMPELTED==TRUE) {
"UPDATE tblusers SET IsComplete=1";
}
Now we have that bit out of the way lets look at the basic logic.
A drip mailer simply once a day needs to check your DB for pending actions and then send out notification emails as required. We can achieve this with a basic headless cron task running on the linux crond. You can find examples of running a php script via cron on google pretty much first response is exactly what you want. I'll not get into that but more into the actual cron script.
So now we know when the user signed up for your site, we know if their profile is complete and when we last warned them.
Our cronjob is nice and simple all it has to do is check is profile complete if not then check dates and send email.
$query = "SELECT EmailAddress,SignupDate,LastWarnDate FROM tblusers WHERE IsComplete=0"; //we don't need to bring back the completed users so for speed we look at uncomplete only
if (strlen($query->LastWarnDate) < 5) { // this is a little nasty but will work NULL is in the db field which returns 4 characters on strlen so a quick check that its < 5 means that we don't have a proper date in the field. There's better ways of doing this i'm being brief
// ok no last warn date so check sign up date vs now
if (DATE_DIFF($query->SignupDate,now()) >=3) {
//3 days or longer since signups so do first warn
"update tblusers SET LastWarnDate=NOW()";
mail(); //standard php mail function for sending email you can use swiftmail or another component if you like
} // its been less than 3 days so do nothing no need for an else
} else {
//we have a last warn date so check warn date vs now
if (DATE_DIFF($query->LastWarnDate,now()) >=3) {
//3 days or longer since last warn date so update last warn date to now and email
"update tblusers SET LastWarnDate=NOW()";
mail(); //standard php mail function for sending email you can use swiftmail or another component if you like
} //its been less than 3 days so do nothing no need for an else
}
So thats it very basic logic flow and example not valid php but you should be able to base your final solution on the code pretty easy.
Schedule the cron job to run at midnight every night and you're done.
As discussed with #Dave under his answer, I'm considering tracking the drips in a dedicated table in order to buy myself more flexibility...
Create a drips table with the following fields:
id (INT)
type (INT or ENUM) This maps to a specific type of drip with its corresponding conditions, etc
user_id (INT) foreign key linking to the user who will get the email
user_email* (VARCHAR) Optionally, the user's email address
count (INT) Tracks how many times it been sent for use in limiting the number of drips
last_sent (datetime) Tracks the date of the last time it was sent for use in maintaining the interval
When actions happen that potentially relate to drips, I check this table and add/delete scheduled drips accordingly. For example, when a user completes their profile, I would check this table and delete the corresponding drip. (<--This is a shortcoming of this approach, IMO.) I worry a bit about this part because some of the drips depend on various factors that may be difficult to keep track of throughout the code.
Every night, a cron job runs that loops through the drips and sends the emails that correspond to each type and which match the interval set in the code that corresponds to each. The job increments the count field and possibly also deletes records which have maxed out (maybe in query at the end of the job).

Allow access to a game every few hours using mysql and php without long code?

I have some games I have programmed for members to play. I usually allow members to play games every day, and I have a cronjob resetting the value at midnight to allow access to the games again the next day.
I constructed a new game, and I wanted it to allow members to play every 2 hours. I realize I cannot do this with a cronjob, because members will play the game at different times.
I know this probably sounds bad, but I'm not very familiar with timestamps, so I really don't know where to start. I haven't really had any reason to look into it until now. I'm guessing that the time or now function will accomplish this when compared, but again I cannot find the relevant situation in the manual about doing this with mysql and successfully submitting that data in the same format.
I've seen examples of other programmers doing this in a certain way, but it seemed they went to unnecessary lengths to make it work. The example I've seen would add a lot of lines to my code.
If this is a repeat question, I apologize, but I don't know what keywords to search for in this situation. All I have gotten is javascript countdowns.
Well the first thing that you're going to need is a way to determine when each member has played the game. So you will need to create a table with the following information:
MemberID
GameID (In case you want to support more than just 1 game in the future using this model)
DateTimePlayed
So now the first problem you have to solve is "Has player X played game Y in the last 2 hours?" That can be solved with a simple query:
SELECT * FROM MemberGameHistory WHERE MemberID = X and GameID = Y and DateTimePlayed > DATE_SUB(NOW(), INTERVAL 2 HOURS)
If you're happy that they haven't played it and decide to let them in, then you need to insert a row so that the next time you run the query you'll see that they've done it:
INSERT INTO MemberGameHistory (MemberID, GameID, DateTimePlayed) VALUES (X, Y, NOW())
Does that solve your problem?

Method for preventing a visitor from making more than 2 posts per day (PHP MySQL)

I've been searching for hours for a solution and either I can't find the right words to describe what I need in the search engines, or I'm just bad at finding things.
Here's the situation:
I'm currently making a website and I have a section where visitors can post messages, kind of like a "guestbook". However, I want to limit an IP address to 2 posts per day. I thought it'd be easy at first, just insert the IP address, date, and time along with all the other data into the mysql table and then do a comparison of the times and dates from each ip. Something like that.... Then as I got to working on it, so many questions came to mind. How would I compare the entries if the IP has posted more than 2 messages over a number of days? How would you even start comparing the date and time accurately? What's the best time and date format for comparison? Is there a better way such as self expiring data that you can compare to? And so on.. Sorry if this seems like such a simple task but I am having a hard time finding the answers. Tried googling everything such as "mysql php time limit", "php mysql prevent spam timer", "php mysql timer like megavideo" etc.
Just to clarify, I need a good method for preventing a visitor from posting more than 2 message per day. This is a "guestbook" kind of thing so any visitor can post. No logins.
Thank you in advance!
Create a table called exceptions with structure id, ip, date
and when user posts something, execute a query like :
$ip = $_SERVER['REMOTE_ADDR'];
$query = "insert into exceptions set ip = '{$ip}',date = 'NOW()'";
and before let user post something add this:
$ip = $_SERVER['REMOTE_ADDR'];
$count = mysql_num_rows(mysql_query("select count(*)
from exceptions where ip = '{$ip}'
and date > DATE_SUB(NOW(), INTERVAL 24 HOUR)"));
if($count> 2) {
echo 'You have exceeded posting limits, please try again in 24 hours';
exit;
}
something like this:
posts_in_last_24_hours = select count(*) from posts where ip=? and date>(NOW()-86400) -- 24 hours ago
if that is 2:
fail
else:
post message
If you record in your database the IP on every post, you can check if it has posted more than 2 times in the last X days with a query counting the number of records with that IP in the last X days, something like this:
SELECT COUNT (IP) FROM posts_log WHERE IP = 'the_user_ip' AND post_date > (NOW() - (X * (60 * 60 * 24)))
Using a trigger
Record the IP and store that in the guestbook table.
Then create a trigger like so:
DELIMITER $$
CREATE TRIGGER bi_guestbook_each BEFORE INSERT ON guestbook FOR EACH ROW
BEGIN
DECLARE posts_today INTEGER;
SELECT COUNT(new.ip) INTO posts_today FROM guestbook
WHERE ip = new.ip AND postdate = new.postdate;
IF posts_today > 1 THEN BEGIN
//Force error by selecting from non-existing table
//this will prevent the insert from happening.
SELECT no_more_than_2_post_per_day_allowed
FROM before_insert_guestbook_error;
END; END IF;
END$$
DELIMITER ;
Now you can just do inserts in you php code with worrying about the daily limit.
The trigger will take do the checking for you automatically.
Using insert .. select
If you don't want to use triggers, use an insert ... select statement.
First make sure that field ip is defined in the table definition as NOT NULL with no default.
This will make the following insert fail when trying to insert a null value into the guestbook table.
<?php
$name = mysql_real_escape_string($_GET['name']);
$post = .....
$ip = ....
$query = "INSERT INTO guestbook (id, name, post_text, ip, postdate) SELECT
NULL AS id
, '$name' AS name
, '$post' AS post_text
, IF(guestbook.count(*)>=2,null,ip) AS ip
, CURDATE() AS postdate
FROM guestbook WHERE ip = '$ip' AND postdate = CURDATE()";
Of course you can put the IF(count(*) >= 2,null,...) in the place of any column that is defined as NOT NULL in the table definition.
Links:
select...insert: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
triggers: http://dev.mysql.com/doc/refman/5.1/en/triggers.html
You could implement this simply with cookies. Anyone determined enough to get round the posting limit would be able to get round an IP block anyway, since proxies and dynamic IPs make it really easy. So blocking by cookie or by IP are about as useful as each other (not especially), but cookies are easier to implement:
If you store a counter in the cookie and set the expiry date to be 24 hours in the future.
You can then increment the counter when the user posts an entry, and simply check the counter to see if they've reached their limit.
That way you don't have to worry about mucking about with a database and any performance issues it can introduce.
Building upon Neville K's captcha point. If spam is your main concern, try out a negative captcha - it doesn't impact the user's experience since they never see it.
You've already got plenty of reasonable looking answers, so I won't add anything to that - but I do think you need to be careful using IP address as the unique identifier of the visitor. It's not a reliable way of identifying users - for instance, most people within a single company/university/government installation will appear to come from the same IP address, so this implementation would limit everyone within that structure to 2 posts per day.
The best way of avoiding spam is to include CAPTCHA - it's a pain in the backside for users, but it reliably foils robots; unless your site is super high value, spammers won't be motivated enough to have human beings post spam.

Categories