WordPress Email, Custom Post types and Email Subscriptions - wordpress

I have something a client wants me to build, and I can with wp_mail, but I am wondering if how it should be built is fessable - no they dont want to use third party websites or software.
Essentially a widget will take in the clients email address, with this we can:
Have some kind of interface so we can say that send out 5, 10, 15 posts of category x, y, x on a daily, weekly or monthly basis
Thats not hard, but the question is: how would I store the emails that come in? a new column?
Use these emails and a custom post type to create email templates, newsletters and so on that could be sent to a set of emails (in this case all emails stored for now) at a specified time.
This one isn't hard either, its the custom post type part, how would I create a custom post type that when a post is published the post is not published the same way a post is, or a page. but instead its stored like one, but I can use its content in an email body instead of displaying it like a post or page.
essentially I shouldn't be able to go to:
site.come/email_templates/post_id
So the second one is a bit more complicated but I am wondering how you guys might approach this situation or idea.

Here are some thoughts when it comes to the e-mail subscription part. As for the custom post types - I don't have much experience with those, sorry :)
If you want a quick and easy solution for the e-mail subscriptions, create a wp option (see http://codex.wordpress.org/Function_Reference/add_option) that is essentially a hash table that maps categories to keys in the table.
For each category in the hash table, store an array of userIDs and/or e-mails of the users that are subscribed to that category.
Once you have this data structure in place, it's fairly easy to manipulate and use in with wp_mail. Here is some example code that I've written for one of my plugins:
$subscribers = get_option('subscribers');
$categories = get_the_category($post->ID);
if( !empty($categories) && !empty($subscribers)){
$emails = array();
//Go through each category and accumulate the necessary e-mail addresses
foreach($categories as $category){
$catID = $category->term_id;
if( !empty($subscribers[$catID]) ){
foreach($subscribers[$catID] as $userID => $trash){
$user = get_userdata($userID);
$userEmail = array( $userID => $user->user_email );
if( !in_array($userEmail, $emails) ){
$emails = $emails + $userEmail;
//you can use something like implode(", ", $emails)
//in the Bcc: part when you send out the e-mail.
}
}
}
}
}
Some things to note:
This is a quick and dirty solution. If the number of categories and number of subscribers grows big, you're better of creating a table in the database and maintaining it that way
Make sure to think of situations when categories are deleted (i.e. hook into actions when categories are deleted) and how that will affect your datastructure
The hash table approach works well assuming categories are NOT deleted/added frequently
Good luck!

Related

Use "Team Members" custom post type instead of Author for blog posts

For SEO purposes....a client would like to have author links point to the Team member's bio page instead of the default author page....for example:
There's a blog posts written by user A. The author link now points to:
/author/usera
but they would like it to point to
/our-team/user-a
"Our Team" is a custom post type, and User A is a post within it.
I've tried a few workaround solutions, but haven't found a good way to establish the relationship between the author and the team member. If I could just add the team member from that custom post type when choosing the Author...that would solve my problem, though I imagine that's fairly complicated - but hopefully gives an idea of what I'm trying to accomplish.
My workaround so far is to rewrite the author base to the slug of the custom post type, which takes care of half of it, but there's still no relationship between the author and team member, so I use the_author_meta(user_url) to get the "Website" field in the user profile, and I put in the url of the team member there.
It works, but doubles the work since you have to add the Team Member to Our Team, as well as add them as a user/author, and then requires the knowledge of the admin adding the user/author to add the bio url in the website field, otherwise...it won't work well, so I'd love a cleaner solution.
Let me know if that makes any sense or not and if there's a better way to do this...
Thanks!
Currently, I cannot see an automated mapping of user account → team member post happening. So, there are multiple ways to achieve this by manually mapping user accounts to a team member post.
Set the author's website to the URL of the team page
Advanced Custom Fields: creating a field group that is shown for all user accounts and includes a Post field (limited to Team posts), so you can select exactly one team post for each WP user manually
I will show you the first option.
Assume, each user account (Users) has the URL to the team member page set, e.g., in the user profile of usera you see:
Website: https://your-site/our-team/user-a
Then you can add a filter to modify the author link like so, adding this to your functions.php or own plugin:
add_filter( 'author_link', 'team_author_link', 10, 3 );
function team_author_link( $link, $author_id, $author_nicename ) {
$userinfo = get_userdata($author_id);
// if the user's Website field is not empty, replace the author link:
$link = empty($userinfo->data->user_url) ? $link : $userinfo->data->user_url;
return $link;
}
Now, you will have all your author's links linked to their "website", which hopefully has been set to the team member page.
This can also be done with Advanced Custom Fields a bit prettier where you could add a field group shown for User Roles -> All, with the field group having a "Post"-type field named "team_post", matching only the team custom post type. It would look similar to this: https://i.stack.imgur.com/LLgWv.png
(your post type most likely will not display as "Staff member", but most likely "Team").
Then, you can select a Team post in each author's user profile and change the filter function to this:
add_filter( 'author_link', 'team_author_link', 10, 3 );
function team_author_link( $link, $author_id, $author_nicename ) {
$team_post_id = get_field('team_post', $author_id);
// if the team post is set, get the permalink to the team post:
$team_link = get_permalink($team_post_id);
$link = ($team_link !== false) ? $team_link : $link;
return $link;
}
Keep in mind that in both cases, each user can tamper with their URL. Using Advanced Custom Fields, it would also be possible to create an admin-only options page where you can map user accounts to Team posts - but this is a bit more complex.

Executing code related to the specific contact form the user is sending

I'm quite new to Wordpress, so please forgive me and correct any mistake I'm making, I'm willing to learn and improve :)
I set up multiple contact forms for applying to fitness courses. People need to fill them, and I get an email with their written data.
What I'm trying to do now is execute some PHP code that writes data into a MySQL database whenever the user correctly fills and sends a contact form.
I also need every contact form to have a unique code "attached" to it, because the PHP code needs this code to write the data inside the database. (simply put, every course has its unique code that i need to write in the database along with the user's data).
So far as I understand, I need to use add_action( 'wpcf7_before_send_mail', 'my_function' ); in a snippet inside functions.php. What I'm trying to achieve now is to attach this code to every contact form (but it mustn't be visible to users) so that my php snippet reads this code and correctly edits the database.
Any clue on where to look? I don't need the code written, just some ideas!
Thank you in advance, have a nice day everybody.
EDIT: I found out there are "hidden fields" in CF7. So, i added these to my test contact form:
[hidden idcorso "6"]
[hidden idgruppo "0"]
Then i'm using this snippet, but it doesn't work:
add_action( 'wpcf7_before_send_mail', 'process_contact_form_data' );
function process_contact_form_data( $contact_data ){
$idcorso = $contact_data->posted_data["idcorso"];
$idgruppo = $contact_data->posted_data["idgruppo"];
if (is_user_logged_in()) {
$idutente = get_current_user_id();
$data = current_time('d-m-Y - g:i');
$stato = 1;
$wpdb->insert("fis_iscrizioni_2018", array('id_utente' => $idutente, 'id_corso' => $idcorso, 'data' => $data, 'stato' => $stato, 'id_gruppo' => $idgruppo) );
}
}
Any clue?

Change user_nicename after registration

Say we have a a mother site. Then we have a user registration form on a 3rd party site and a user register system which is processing the whole registration process and in the end will send the user login details in the mother site's database (mysql insertion, again no user_register function). Since there are 2 completely different browser sessions, no actions can be hooked on the mother site during or after registration.
So, let's say we will have stored the users in the database with logins like aaa#bbb.cc (weird, yes) and having a name and the user_nicename appearing like aaa#bbb.cc
Question:
What is the best aproach, wp action/function to be hooked, that once the user is stored in the mother site's database, to write a function to change the user nicename in something like aaa-bbb Automatically of course.
Is there a function/hook suggested for such cases?
The below code didn't helped me, since as I told above, I think the user_register action can't be triggered when a 3rd party site registration is processed:
add_action( 'user_register', 'myplugin_registration_save' );
function myplugin_registration_save( $user_id ) {
$info = get_userdata( $user_id );
$args = array(
'ID' => $user_id,
'user_nicename' => $info->first_name . '-' . $info->last_name
);
wp_update_user( $args );
}
The question as worded is really hard to understand. If I'm reading it correctly, you have two websites. Site One is where people are registering. When they complete registration on Site One something runs that creates a new user in the Site Two database by doing a direct sql insert, not by using any native WP functions.
If that's the case, why don't you simply manipulate the user login before you insert it into the Site Two db? You can't do it via a WordPress hook b/c WordPress is never being called. Hooks are just callback functions sprinkled through the WordPress code. When something happens, like a new user is created, there is a hook that you can assign a function to -- something "Send me an email." If WordPress doesn't handle the new user creation then the hook never gets called.
If you have to do the manipulation after the data has been inserted you'll probably need to look at using a cron job that runs every X amount of time looking for new records in the wp_users table.

Wordpress Plug-in - Trigger e-mail based on a specific date

I currently have a registration form for people to signup and pick a date for an "appointment". They get sent an e-mail right after filling it up with the details. I need another e-mail to be sent a day before their chosen date to remind them, but that can't be fulfilled by plugins I currently have.
Does anyone know of any Wordpress plug-in that allows the sending of an e-mail message (with a template and user specific data) based on a specified date?
Any piece of information or advice would be highly appreciated. Thanks!
How I would approach this would be with Wordpresses event scheduling. When a user submits the form to schedule their appointment, set a new action for the reminder email:
// Set this when you send the confirmation email
// Set the $unix_timestamp to be whenever you want the reminder to be sent.
// Args can be an array of the data you will need. Such as the users email/appt date
$args = array(
'email' => 'email#email.com'
);
wp_schedule_single_event($unix_timestamp, 'set_reminder', $args);
Now we have to catch that, and create a function to actually create and send the email (assuming you use a similar process):
add_action('set_reminder','do_reminder');
function do_reminder($args) {
// $email = $args['email'], etc.
// send reminder email.
}
I recommend Wysija Newsletters. You http://wordpress.org/extend/plugins/wysija-newsletters/. You can use template and user specific data in your email with this plugin.
If you are comfortable with writing your own code(I guess you are more or less ok with that), you can use the WordPress Schedule API(okay, maybe that's not the official name, but it works). Basically it's kind of a cron-job, but for WordPress. It has one downside though - it will only trigger on time, if WordPress is rendered(in other words accessed, so that it's code will execute). That can be easily fixed by adding a simple cron-job to your hosting account, that will simply access your home page every X hours.
You can find useful information on the API here.
Basically what you should have inside of your scheduled function is to get the records of people that should be sent reminder emails(you should probably store additional information about whether a reminder email has been sent or not) and send them the emails. I don't know what is the way you're storing the information from the registration form, but if you are using a Custom Post Type, then things should be pretty easy for you.

Drupal module to control user post frequency?

We've been having a new type of spam-bot this week at PortableApps.com which posts at a rate of about 10 comments a minute and doesn't seem to stop - at least the first hour or so (we've always stopped it within that time so far). We've had them about a dozen times in the last week - sometimes stopping it at 50 or 60, sometimes up to 250 or 300. We're working to stop it and other spam bots as much as possible, but at the moment it's still a real pest.
I was wondering whether in the mean time whether there's any sort of module to control the frequency a user can post at to e.g. 50 an hour or something like 10 in an hour for new users. That at least would mean that instead of having to clear up 300 comments 50 at a time in admin/content/comment we'd have a smaller number to clear. (A module to add a page to delete all content by a user and block them would also be helpful!)
I believe that there's a plugin to do this available for WordPress, but can't find any such thing for Drupal.
For your second question, i would have a look at the code of the User Delete module (click).
The module also disables the user account and unpublished all nodes/comments from a certain user. By extending the code, you could easily create another possibility to unpublish + delete all nodes/comments from a certain user and blocking the account.
After the unpublish code in the module, you should just put delete code (in sql if the module is selecting by a sql-query or by using the drupal delete functions).
Another option would be so make a view (using the view module) only to be viewed by administrators, where you choose a certain user using the filters and then lists his/her posts. Then in the node-contenttype.tpl.php you place a button that calls a function which deletes all nodes/comments and the user.
First problem (post frequency)
I've been thinking about the comment post limit. If I remember correctly Drupal stores comments in a seperate table and has comment specific functions.
I'd create a new module and using the comment_nodeapi function i would check in the operation 'insert' how much comments the current user has already made within a certain timeframe.
To check this I would write a custom sql query on the database which takes the count of alle comments made by uid where the post_date is larger then NOW-1hour. If that count is larger then 10 or 15 or whatever post frequency you want then you give a message back to the user. You can retrieve the user id and name by using the global $user variable.
(example: print $user->name;)
You have to check on your own for the sql query but here's some code when you have the amount:
<?php
function comment_nodeapi(&$node, $op, $arg = 0) {
switch ($op) {
case 'insert':
//PLACE HERE THE SQL TO GET THE COUNT
if($count > 15){
$repeat = FALSE;
$type = 'status'
drupal_set_message("You have reached the comment limit for this time.", $type, $repeat);
break;
}else{
db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->changed, $node->uid);
break;
}
}
}
?>
(this code has not been tested so no guarantees, but this should put you on the right track)
I would suggest something like Mollom (from the creator of Drupal). It scans the message for known spam pattern/keywords/... and if this scan fails, it displays a CAPTCHA to the user to make sure that it's a real human that wants to enter content that has the same properties like spam.
They offer a free service and some paid solutions. We are using it for some customers and it's worth the money. It also integrates very well in Drupal.
Comment Limit is probably what you need.
http://drupal.org/project/spam
http://drupal.org/project/antispam - with akismet support

Resources