For a wordpress site I have to implement a reminder that will be send 30 days after the creation of a post in wordpress.
For example:
Author creates a post, 30 days after the creation of this post the author will get a mail on the email-address which he/she filled in at the admin profile dashboard.
The mail needs to contain a url to the original post.
Are there any available plugins that could help me or should I write a custom function ?
Thanks in advance.
The problem you're going to run into is that PHP runs when a user makes a request. So, if no one visits the site on the right day or at the right time, the code you want may not run. And even if they do, do you want to slow down a random users request for this functionality.
It's best if you look into a Scheduled Task (windows) or Cron Job (linux). These utilities can be used to run PHP scripts at specific times or with specific intervals (every hour, every day at midnight, etc.). Then you create a PHP script that does the work of finding the specific posts and sending emails.
If your hosting provider doesn't allow access to a scheduling utility. You could setup your own computer, or another computer with a scheduled task to call a specific PHP file that does this work.
You need Blog Update Reminder.
I have modified this plugin to suit my needs. I´m sure you will like it ;-)
http://wordpress.org/extend/plugins/blog-update-reminder/
For a temporary solution I did the following:
I downloaded the plugin 'crony cronjob manager'
This plugin let's you run custom php at a specific time-interval.
My custom php looks like this:
<?php
$query = "SELECT * FROM wp_posts
WHERE post_type = 'catalogus'
AND post_date BETWEEN '" . date('Y-m-d', strtotime('-30 days')) . "'
AND '" . date('Y-m-d', strtotime('-29 days')) . "'";
$allposts = $wpdb->get_results($query);
if($allposts){
foreach ($allposts as $post) {
// get post name for url
echo "http://xxxxxx.xxx/product/".$post->post_name;
// get author email to send mail to.
$to = get_the_author_meta('email',$post->post_author);
$subject = "XXXXXXXXXXX";
$headers = "From: XXXXX <noreply#XXXXXXX.nl>";
$message = "Dummy message";
wp_mail( $to, $subject, $message, $headers, $attachments );
}
}
else{
echo "No posts";
}
?>
This is still no perfect solution, because like Chris mentioned above, this cronjob will only run if a visitor makes a request, my next step is to write a real cron job or scheduled task that will execute the code above.
Related
I am using the wp_schedule_single_event() function to create a wp-cron job that sends an email to the specified user at the specified time.
Mostly this wp-cron job is successfully created and the users get informed in time. But sometimes it just doesn't work.
Whats especially strange is that wp_schedule_single_event() always returns true (which means that it was executed successfully) even when the wp-cron job isn't created (I check that with the WP Crontrol plugin).
My code (write_log: custom function to log the given strings, time: the corresponding timestamp):
write_log('User ' . get_current_user_id() . ' now tries to create the addProductsExpired cron job with timestamp: ' . time);
$success = wp_schedule_single_event(time, 'hook_addProductsExpired', array(get_current_user_id()));
if (!$success) {
write_log('The creation failed!');
}
write_log('User ' . get_current_user_id() . ' now tries to create the sendReminderMail cron job with timestamp: ' . time);
$success = wp_schedule_single_event(time - 60 * 60 * 24, 'hook_sendReminderMail', array(get_current_user_id()));
if (!$success) {
write_log('The creation failed!');
}
I should also note that I never accomplished it to reproduce the error by myself
I so far tried:
updating Wordpress
studying the logs
executing the function with accounts of users where it previously failed (it worked on my pc and also on the pc of the user in future executions)
modifying parameters in the user entry of affected users
manually executing the function with the parameters it previously failed
rewriting and optimising the whole function
None of them worked or threw an error i could debug.
I am now using actionsheduler.org as suggested by Terminator-Barbapapa
in his comment to my question. So far I haven't experienced any issues.
I have a wordpress website that allows a user to set up a reminder for a certain day, it stores it in a database where it can either be displayed when the user logs in, or send out an email to them.
I followed the example code given in http://codex.wordpress.org/Function_Reference/wp_cron and have placed the code below into the main .php file of a plugin I have written which functions perfectly in all other ways.
if ( ! wp_next_scheduled( 'checkReminderEmails' ) ) {
wp_schedule_event( 1411693200, 'daily', 'checkReminderEmails' );
} //1411693200 is the unix timestamp for 1am a couple of days ago
add_action( 'checkReminderEmails', 'sendReminderEmails' );
function sendReminderEmails()
{
$table_name = $wpdb->prefix."reminders";
$query = "SELECT * FROM $table_name WHERE sendReminder = 1 and reminderDate = CURRENT_DATE( )";
$appointments = $wpdb->get_results( $query);
foreach ( $appointments as $info )
{
$message = "Hello here is your reminder.";
$toAddress = $info->userEmail;
$subject = "This is your reminder.";
wp_mail( $toAddress, $subject, $message);
}
} // end sendReminderEmails()
I have checked the wp_options table in my PHP database and can see the following code there
{s:18:"sendReminderEmails";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:5:"daily";s:4:"args";a:0:{}s:8:"interval";i:86400;}}}i:1411693200;a:1:
I can receive other emails from the website using wp_mail() so I know that the functionality is supported by the server, and I know that the wp_cron jobs aren't fired until the website is visited after the time has passed, but I have been unable to get this cron job to fire correctly. Am I missing something obvious?
Edit: For anybody wondering, I used the wp-cron-dashboard plugin (https://wordpress.org/plugins/wp-cron-dashboard/) despite the warning that it hasn't been updated in 2+ years to check that my cron job was scheduled properly.
I also had to add global $wpdb; to the top of my function, the reason it was failing to fire was because without declaring that I was unable to use the get_results() function.
I also discovered that if you go to wp-cron.php you will manually force any scheduled cron jobs to be fired, and all output will display there, so it is possible to debug a cron job by adding echo statements and going to that page.
I know this is old but one thing I see right away is you need global $wpdb; as the first line of the sendReminderEmails() function, otherwise it's going to bomb.
I often quickly test cron functions in my front-page.php by adding something like sendReminderEmails(); exit; to the top, just as a sanity check that the function works at all.
Hoping some of you out there are great with php!
Basically the guy who made this is MIA so I can't ask him what I need to do to fix the problem we are having.
Background:
We are a locksmith company that uses a custom web app to inform our locksmiths on the road when they have a new job. This web app also does a few extra things like providing gps location, time taken at the job and the ability to have save signature from the client upon work completion.
Problem:
The app works by picking up an email sent from our account management application called E3, the email (example: http://cl.ly/image/2E433O330T0N) is read by this web app, parsed into both an email and a web page and sent to the locksmith to view his new job. When the locksmith arrives at the web page on his phone (example: http://cl.ly/image/0P1I0R0h0O3K), he can see the job details including the Name, address and contact details for the client. The problem is though, because Job Notes isn't assigned a heading in the original email the code has to work out where Job Notes is located, this is the part that has the problem as the web app is no longer showing the data in Job Notes. Job Notes is important because it tells the locksmith what he needs to fix. This worked previously but has now just stopped working and we aren't sure why.
How the data is transferred to the web app is very interesting, instead of having a database to store data to, it is put in the address bar and then the webpage interprets the code and formats it into the page.
For example, this is how the current link looks (data taken out, replaced with xxxxxxx):
http://www.xxxxxxx.com/apps/xxxxxx/on-my-way?client=xxxxxx&company=xxxxxx&mobile=xxxxxxx&phone=xxxxxxx&contact=xxxxxxxx&addressData=Array&addressIndex=3&streetAddress=xxxxxxxxx&addressLocality=xxxxxxxx&postcode=xxxxxxx&city=xxxxxxx&clientEmail=&jobDate=11/22/2012&jobTime=1:30:00%20PM&jobID=xxxxxx&jobAMPM=PM&adminEmail=xxxxxxx&noreplyEmail=xxxxxxxxxx&companyPhone=xxxxxxxx&staffEmail=xxxxxxxx&staffName=xxxxxxx&staffPhone=xxxxxxxx
Previously, when working, this link had a jobNotes field added:
http://www.xxxxxxxx.com/apps/xxxxxxxx/on-my-way?client=xxxxxxxx&company=xxxxxxxx&mobile=xxxxxxxx&phone=&contact=xxxxxxxx&addressData=Array&addressIndex=4&streetAddress=xxxxxxxx&addressLocality=xxxxxxxx&postcode=xxxxxxxx&city=xxxxxxxx&clientEmail=xxxxxxxx&jobNotes=Quote%20on%20installing%20new%20keying%20system%0A%0AAlso%20would%20like%20a%20Quote%20on%20Install%20CCTV%0A%0ASub%20Total%3A%202%2C236.36%0AGST%3A%20223.64%0ATotal%3A%202%2C460.00%0A%0AMISC&*jobDate=11/19/2012*&jobTime=2:00:00%20PM&jobID=xxxxxxxx&jobAMPM=PM&adminEmail=xxxxxxxx&noreplyEmail=xxxxxxxx&companyPhone=xxxxxxxx&staffEmail=xxxxxxxx&staffName=xxxxxxxx&staffPhone=xxxxxxxx
The code:
This is an extract from e3-parser.php, the main file that translates the data from the e3 email to the web app.
// Job notes
if ($this->clientEmail) {
// REMOVED NOW THAT EMAIL IS BEING PUT ON THIRD LINE OF ADDRESS
// // If customer email present grab everything after it save it as job notes
// preg_match("/$this->clientEmail[^-]+/",$e3Output,$matches);
// $result = implode("",$matches);
// $notes = trim(str_replace($this->clientEmail,'',$result));
// $this->jobNotes = rawurlencode($notes);
// } else {
// Fall back to grabbing everything after the time
preg_match("/AM[^-]+/",$e3Output,$matchesAM);
preg_match("/PM[^-]+/",$e3Output,$matchesPM);
$resultAM = implode("",$matchesAM);
$resultPM = implode("",$matchesPM);
$notes = trim(str_replace('AM','',$resultAM) . str_replace('PM','',$resultPM));
$this->jobNotes = rawurlencode($notes);
}
Question here is, does it successfully grab the data listed after the Required Time field? (example email that it's reading from: http://cl.ly/image/2E433O330T0N)
Here is the code that places the parsed data into the web page:
// Create job link
$url = $e3->create_job_url('http://www.prvgroup.com.au/apps/jobbook/on-my-way?');
$linkName = "View job details";
$href = '<a class="btn btn-small" href="' . $url . '&staffEmail=' . $staff- >staffEmail . '&staffName=' . $staff->staffName . '&staffPhone=' . $staff->staffPhone . '">' . $linkName . '</a>';
This is sent to the locksmith via email informing him of his new job on the clickable link "View job details". The link is impregnated with the data needed. However from the looks of it the data for jobNotes isn't there. My backups of this code display the exact same thing here when the code was displaying jobNotes so I'm not exactly sure how it is putting that field in.
If you got this far, well done! I hope I was clear enough with what the issue is but if you need anymore clarification, just ask!
Cheers,
Marc
After looking through your code you are only running the preg_match if there is a clientEmail. From the sample emails above it does not look like you are ever executing this code because there is no client email or it is not found using the preg_match. The specific location to look into is on line 113 of the e3-parser.php file. You will see this:
if($this->clientEmail)
{
//matching code here.
}
on line 109 and 110 you are looking for an email address and either not finding one or it is looking in the wrong location. At any rate, you should execute this code regardless of whether there is an email address or not. The notes must be set for later use, right now nothing is being set. Removing this if statement should resolve your issue.
First Part:
I am trying to write a script to email us when a service call is not paid.
Heres' what I have got started:
$query = "SELECT * FROM service";
$result = mysql_query($query);
while($row = mysql_fetch_row($result)){
$id = $row[0];
$dateEntered = $row[1];
$type = $row[2];
$account = $row[3];
$dateCompleted = $row[4];
$notes = $row[5];
$status = $row[6];
foreach($status == 'Unpaid'){
mailBadAction($id, $account, $status);
}
}
I am not sure if I wrote the foreach right (probably didn't, and I'm not in environment where I can just try it because its hooked into everything else.)
But basically, it will load all of the service calls in my while statement. I want to check each records $status, and check if it is 'Unpaid', and if so, run the function mailBadAction() and pass the $id, $account, $status, $dateEntered to the function. I only want this to happen ONCE a day.
Second Part:
I need this to run everyday at a certain time, once a day. I have zero understanding of cron jobs so I think that is out unless someone wants to help me out with that. But what I have learned is if I just include this page on the index or login page, it will run when someone simply hits the login page. But this will run it for every single time someone hits the index page.
Can someone help out?
As you are already in a loop, going though the results, so you don't need a foreach, you just need if:
if($status == 'Unpaid'){
mailBadAction($id, $account, $status);
}
And if you are on a linux environment, you need cron to run something once a day.
The easiest thing to do (if your system has it...), is add the php script to /etc/cron.daily and make it executable. Your script would look something like (depending on the environment...):
#!/usr/local/bin/php
<?php
// your script
?>
And you really should test it...
Jeroen's answer is correct, you need an if statement.
You could get around setting up a cron job by adding a database check to make sure it's been at least 24 hours since it last sent out emails, and updating that timestamp. But that's honestly more trouble than it's worth. It would block and slow down immensely as it processed data and sent emails, and some poor sap would be sitting there wondering why the page is taking forever. Learning how to setup a cron job would be much more valuable.
I think you got the foreach syntax wrong:
foreach ($array as $value) {
//here you can use $value as the current array field
}
But like said before, you can either adjust your query only to give you the fields that are unpaid:
SELECT id,account,status FROM service WHERE status = 'Unpaid'
(i dont know how exactly your table looks like, but i imagine that structure)
Now every result coming from your DB is "Unpaid", so the testing if(status=='Unpaid') is unnecessary.
For the Cronjobs look on google after "cron php" and you may get :
http://www.thegeekstuff.com/2011/07/php-cron-job/
That means you pop the Script completely from the main site and run it as an stand-alone system, without acces from the web.
I would like to automate the process of sending this email. I mean when a condition is met then the email should automatically be sent to the given email addresses which is already given as hard-coded values. So for an example in my case a Technician has to complete 40jobs a day and if he finished 35 at the end of the day an email should be sent to the supervisor(provided his email id is already given) with Subject name and the body should be like ” The Technician 1234 has completed only 35 jobs for the day instead of 40. I was wondering how can implement this as Im very new to the field of PHP. Please anyone help me out. If possible please provide me with an example.
Thanks
Dilip
You could run a cron that uses the php mail function to send a report about each programmer at a set time each day. The cron script would look something like:
<?php
$to = 'admin#mydomain.com';//the set up email to mail too
$result = mysql_query('select programmer_id, job_count, job_requirement from table'); //query the database
while($job = mysql_fetch_object($result)){
mail($to,'Job counts for ' . $job->programmer_id,"Completed $job->job_count out of $job->job_requirement jobs","FROM: jobcounter#mydomain.com");
}
Have a script check the conditions and send emails, and run it periodically: http://www.google.com/search?q=cronjob
I'm assuming here that your problem is the triggering of the event, rather than the sending of the email itself.
In the example you described, you would need to have a script run at a certain time of day that would check for any condition that would require an email sending, and then send the email. Under any unix-like system, cron is the ideal solution to this. If you are on some kind of basic shared hosting you may not be able to set this up. In that case you would need to set up a task to run on a machine that you do have control over that would call a URL that would run the PHP script. This could be a cronjob, or a Scheduled Task under Windows.
If your example was switched around so that, say, an email was to be sent as soon as a technician completed 40 jobs then you would be able to send the email as part of the script that handled the form submission from the technician whenever he completed a task.
Setup a Cron Job that runs at the "end of the day":
23 55 * * * /path/to/php /path/to/script.php
Have it run a PHP script that can query your Job Store for whatever condition you want to check. For example with Job Store being a database.
$db = new PDO(/* config */);
$result = $pdo->query(
'SELECT count(id) as "tasks_done"
FROM tasks WHERE engineer = "Tom"
AND finished_at = now()');
$result = $result->fetchAll();
if($result[0]['tasks_done'] < 40) {
mail( ... )
}
If the condition is met, send the mail. The above needs refining of course. Dont expect being able to copy/paste it.
Also see:
What is the best method for scheduled tasks in PHP
http://greenservr.com/projects/crontab/crontab.phps
you should use mail() function:
$technicianId = 1234;
$jobsNeeded = 40;
$jobsDone = getJobsDone($technicianId);
if ($jobsDone <= $jobsNeeded) {
mail('supervisor#yourcompany.com', 'Technician '.$technicianId.' slacking', 'The Technician '.$technicianId.' has completed only '.$jobsDone.' jobs for the day instead of '.$jobsNeeded);
}
Could have a cronjob that runs at the end of each day which checks what each technician has done and emails it to the manager.