Matching user meta fields with custom post meta fields - php

I am trying to create a function that matches user's that have the same expertise as a custom post custom field. So if a custom author meta has an expertise of 'Ninja' and the custom post type has a custom field that also has 'Ninja', my email will go out to all those matching user's.
I have the following bit of wp_mail code and can also create user queries using get_users but cannot get the two to work as i need. Any ideas?
add_action('future_to_publish', 'send_emails_on_new_event');
add_action('new_to_publish', 'send_emails_on_new_event');
add_action('draft_to_publish', 'send_emails_on_new_event');
add_action('auto-draft_to_publish', 'send_emails_on_new_event');
function send_emails_on_new_event($post) {
global $post;
$expertise = get_field('expertise', $postid);
$emails = MATCHING USER EMAIL ADDRESSES TO GO HERE;
$message = '<p>Email content will go here ...</p>';
if (get_post_type($post->ID) === 'custom_post_type') {
wp_mail($emails, "Email title will go here ...", $message);
}
}

Have you tried using SQL query actually to get matching emails from database??
something like
$sql = SELECT user.email FROM user WHERE user.expertise = $postExpertise;
$email = database->getRecords($sql); //getRecords() is just general function placeholder, build your own db processor class
...
function send_emails_on_new_event($post) {
...
}
You have to understand, WP is just a tool written in PHP with common functionality, if you want custom functionality, either build it yourself or if you are lucky, find plugin already created with similiar functionality. But you will not always find the plugin you want.
Hence why WP is good only for low-budget websites built by not so great web developers. Because if you can build custom functionality on top of WP, you should already consider if using WP is even good idea in first place

Related

Find unknown post ID in Wordpress programmatically

So, I'm building my first plugin for WordPress. It's a simple plugin that queries a SQL database, gets blog readers emails, and sends them an email whenever a post is updated or published.
The idea is to have an email which tells the reader if the post was updated from its older version or a new post is published. It is also supposed to provide a link to the post for quick reading.
I've gotten this far:
add_action( 'publish_post', 'email_function' );
function email_function( $arg ) {
$link = mysqli_connect("*********", "********", "********", "***********");
if (mysqli_connect_error()) {
die ("There was an error connecting to the database");
}
$query = "SELECT `******` FROM `*******`";
$msg = "There has been a new blog post at The White Road!";
if ($result = mysqli_query($link, $query)){
while ($row = mysqli_fetch_array($result)){
mail($row['email'],"New Post!",$msg);
}}else {
//for testing
echo "break";
}
}
Now, the issue is that in this situation I want this function to be carried out automatically, but to be able to do that I'll have to be able to find a few unknowns programmatically. In particular, the post that is being updated, if the post is being updated or if it's new, the author of said post, and the link to its page.
I've had a look at the WordPress Codex, and all the low-hanging functions (which would be easy for a beginner to understand) require either the post ID or the ID of the author to make that happen. That, of course, does not fulfill the design.
Any help on how to find and use these things would be greatly appreciated. :)
There is a post_updated hook in the Wordpress API that you could attach this function to with add_action.
https://codex.wordpress.org/Plugin_API/Action_Reference/post_updated
You could compare before and after, and if the values of a particular field differ, it would trigger an update. I suppose the easiest would be checking the datetime, alternatively, you could have it check the title if minor spelling/grammar changes don't merit an email.

Wordpress: Output custom user_meta data in registration notification

In WordPress, I have custom registration site for new users. Upon registration, there is an optional checkbox to subscribe to our newsletter. As far as I understand it, it adds the value of the checkbox to the user_meta table (the whole thing has been coded by a company in India, which I woould very much prefer to not involve again, since they delayed their work time and time again and didn't do good work after all).
The corresponding code snippet in my child theme's functions.php looks like this:
<?php echo '<div class="form-row form-row-wide">
<input type="checkbox" name="inter_offers" value="yes"> '; _e('I would like to subscribe to the Kurth Electronic newsletter.','kurth-child'); echo '<br></div>';
return $fields; ?>
add_action('woocommerce_created_customer','adding_extra_reg_fields');
function adding_extra_reg_fields($user_id) {
extract($_POST);
update_user_meta($user_id, 'billing_inter_offers',$inter_offers);
} ?>
(I have left out lines irrelevant to this issue.)
Now, this value is saved internally, but not displayed to me. I would like to show the value in an E-Mail or notification generated by WordPress when the user completes registration, so that we can manually add them to our newsletter list whenever someone chooses to subscribe to the newsletter. The problem is that I only have a limited knowledge of PHP and I don't know where to start.
I should also note that this is not done via the standard WorPress registration form, but by a WooCommerce registration form (I have disabled the standard WordPress registration for security reasons).
I tried using the "Better Notifications" plugin (https://wordpress.org/plugins/bnfw/) for custom notifications whenever a new user completes their registration, but it ignores any php code that I add to the custom notifications body to display the user_meta data.
Any help would be appreciated.
Because the registration is done via woocomerce you may have to look for a notification PlugIN that works with woocomerce, the one you have may just work properly with wordpress core version!
You also could generate a mail via php in the function, so that you get a message with the user mail adress, but i think without php knowledge it is not that easy to use the built in php mailer... (You may need an api there!)
But wouldn't it be better to automatically sign them into your newsletter software? For example for Mailchimp or other systems like that there are quite good wordpress plugins!
You may also be able to include the forms of these PlugIns in your registration form, but without a closer look at this woocomerce registration i can't tell for sure!
I think this will do the trick, it will notify you every time a new user is created and also tell you if they subscribed or not.
function new_customer_registered_send_email_admin($user_login, $user_email) {
ob_start();
do_action('woocommerce_email_header', 'New customer registered');
$email_header = ob_get_clean();
ob_start();
do_action('woocommerce_email_footer');
$email_footer = ob_get_clean();
$user = get_user_by( 'email', $user_email );
$subscribed = get_user_meta( $user->ID, 'billing_inter_offers', true );
woocommerce_mail(
get_bloginfo('admin_email'),
get_bloginfo('name').' - New customer registered',
$email_header.'<p>The user '.esc_html( $user_login ).' created an account ' . ( $subscribed ? ' and subscribed to the newsletter.' : '.' ) . '<br>Email:'.esc_html( $user_email ).'</p>'.$email_footer
);
}
add_action('new_customer_registered', 'new_customer_registered_send_email_admin', 10, 2);
I ended up using the plugin amr users to generate a userlist of all users who had a certain metadata tag set to a certain value (in my case, if they want to recieve a newsletter - the previous developers never bothered to make the data actually readable without extra effort). It is a little clunky to use and not what I originally intended, but it got the job done.

How to filter posts by author on edit.php

Let's suppose the user visits the page of
http://mywpsite/wp-admin/edit.php?author=john-doe
Let's suppose there is an author with the name of 'John Doe' and the given author has three posts. Yet, when I visit the page, I see an empty grid, as if there were no posts created by this author.
I would like to search for posts created by the given user. Based on my research, I can see that people are claiming that something like this should work:
function posts_for_current_author($query) {
if($query->is_admin) {
global $user_ID;
$query->set('author', $user_ID);
}
return $query;
}
add_filter('pre_get_posts', 'posts_for_current_author');
Source.
However, here the author's ID is expected as input, yet, I do not know how to get the author's id by the slug of 'john-doe'.
How can I get the ID of the author by slug and search for posts based on that ID?
EDIT:
This is one failed try, based on NATH's comment:
function wpshock_search_filter( $query ) {
if ((is_admin()) && (isset($_GET["author"])) && (preg_match('/[^a-zA-Z_0-9]/i', $_GET["author"]))) {
$query->set("author_name", $_GET["author"]);
}
return $query;
}
add_filter('pre_get_posts','wpshock_search_filter');
The query still returns no elements. I have var_dumped $query and seen that $query->query["author"] has the textual problem, which is a potential problem. Also, $query->tax_query contains data related to author. I am sorry if this question is worthy of down-votes, I thought others might be confused by Wordpress's database handling as well and thus this question might be useful. Maybe I was wrong.
This should work for you :
get_user_by('slug','john-doe');
EDIT :
From this you can get author object and you can carry forward with your code.
Link
WordPress provides an author_name query variable to you. You can use the following by default:
http://mywpsite/wp-admin/edit.php?author_name=john-doe
Read more about public query variables in the Codex.
I'm wotking on wp front-end and reach similar feauture you are requested
The code you provide are woking current on wp-admin page but any one uses that code prevent his own SuperAdmin account form reviewing other editors posts .
just add !is_super_admin() to your first contition like this :-
if($query->is_admin && !is_super_admin() )
BTW the author's ID are already provided with global $user_ID;
and when you add this $query->set('author',$user_ID); the main query will filter posts result accurding to author ID , see WP_Query();
See this-
https://wordpress.stackexchange.com/questions/89990/how-we-can-get-the-author-id-by-its-name
And, a better way to get posts by an author would be-
get_posts('author'=>AUTHOR_ID);

Sort "contact info" fields in Wordpress user profile

I can add and remove fields in the user profile section with:
function add_remove_contactmethods($contactmethods ) {
// Remove AIM
unset($contactmethods['aim']);
//add Phone
$contactmethods['phone'] = 'Phone';
return $contactmethods;
}
add_filter( 'user_contactmethods', 'add_remove_contactmethods' );
When I view this screen in the backend, the "Phone" field comes last, after some other fields like "Email" and "Website". I guess this is because my added field was added after the default Wordpress fields. How do I sort this, for instance alphabetically, so that my "Phone" field comes in alphabetical order instead of after the default fields? How do I sort the output of $contactmethods without messing it up?
try using ksort
function add_remove_contactmethods($contactmethods ) {
// Remove AIM
unset($contactmethods['aim']);
//add Phone
$contactmethods['phone'] = 'Phone';
ksort($contactmethods);
return $contactmethods;
}
add_filter( 'user_contactmethods', 'add_remove_contactmethods' );
re
UPDATE: So I guess the answer to my original question, is to explain why and how "Website" and "Email" are stored, and how the output is controlled in the backend when you view a profile. Maybe it's an ordered action? I guess "Website" and "Email" are just user meta, but how is the output order controlled. I accept that I might have to write a custom script to sort the output, I just don't know where to begin.
Your right about that, all the new contact fields were added into user_meta table. user_email and user_url are in the users table. The problem you are going to have doing this, is that a filter does not exist to modify the information. You can check the main filters here:
http://codex.wordpress.org/Plugin_API/Filter_Reference
and also you can look at core itself. All the admin templates are in wp-admin so you can look at the variable you need to modify in user-edit.php ($profileuser). Im in no way recommending this, but you could modify the template there, it will be overwritten on the next update of course so thats a drawback to it.
There may be a hook somewhere in admin in the load template process, if you could find one, you could relocate the template location to a theme file and recreate it with the changes you want. But all this seems like a lot of work to include just 2 fields to reorder?
Another approach is to use a higher priority the other when adding the fields. For example, Yoast adding 3 contact methods, and if you want your 'phone' appear before those, set the filter to:
add_filter('user_contactmethods', 'my_contactmethods', -5, 1);
Email and Website cant be re-ordered unless deep PHP coding or javascript re-order or advanced CSS.
if you know the key(s) (check the name fields in the source code), you can add other plugin fields by yourself, and choose exact appearance. A field is only added once if they added twice (!) This is how we use:
function entex_author_contactmethods($contactmethods){
$contactmethods['mail'] = __('Public email', 'entex-theme');
$contactmethods['phone'] = __('Phone', 'entex-theme');
$contactmethods['googleplus'] = __('Google+', 'wordpress-seo');
$contactmethods['youtube'] = __('YouTube URL', 'wordpress-seo');
$contactmethods['facebook'] = __('Facebook profile URL', 'wordpress-seo');
$contactmethods['instagram'] = __('Instagram URL', 'wordpress-seo');
$contactmethods['twitter'] = __('Twitter username (without #)', 'wordpress-seo');
$contactmethods['linkedin'] = __('LinkedIn URL', 'wordpress-seo');
$contactmethods['myspace'] = __('MySpace URL', 'wordpress-seo');
$contactmethods['pinterest'] = __('Pinterest URL', 'wordpress-seo');
return $contactmethods;
}
add_filter('user_contactmethods', 'entex_author_contactmethods', -5, 1);
Happy contact-ing!

Drupal 6 - Content profile fields within page-user.tpl.php

Going a bit mad here... :)
I'm just trying to add CCK fields from a Content Profile content type into page-user.tpl.php (I'm creating a highly-themed user profile page).
There seem to be two methods, both of which have a unique disadvantage that I can't seem to overcome:
'$content profile' method.
$var = $content_profile->get_variables('profile');
print $var['field_last_name'][0]['safe'];
This is great, except I can't seem to pass the currently viewed user into $content_profile, and it therefore always shows the logged in user.
'$content profile load' method.
$account_id = arg(1);
$account = user_load($account_id);
$user_id = $account->uid;
$var = content_profile_load('profile', $user_id);
print $var->field_first_name[0]['value'];
Fine, but now I can't access the full rendered fields, only the plain values (i.e. if the field has paragraphs they won't show up).
How can I have both things at once? In other words how can I show fields relating to the currently viewed user that are also rendered (the 'safe' format in 1)?
I've Googled and Googled and I just end up going round in circles. :(
Cheers,
James
Your content profile load method seems to be the closest to what you want.
In your example:
$account_id = arg(1);
$account = user_load($account_id);
$user_id = $account->uid;
$var = content_profile_load('profile', $user_id);
print $var->field_first_name[0]['value'];
The $var is just a node object. You can get the "full rendered fields" in a number of ways (assuming you mean your field with a filter applied).
The most important thing to check is that you're field is actually configured properly.
Go to:
admin/content/node-type/[node-type]/fields/field_[field-name] to configure your field and make sure that under text processing that you've got "Filtered text" selected.
If that doesn't fix it,try applying this:
content_view_field(content_fields("field_last_name"), $var, FALSE, FALSE)
(more info on this here: http://www.trevorsimonton.com/blog/cck-field-render-node-formatter-format-output-print-echo )
in place of this:
print $var->field_first_name[0]['value'];
if none of that helps... try out some of the things i've got on my blog about this very problem:
http://www.trevorsimonton.com/blog/print-filtered-text-body-input-format-text-processing-node-template-field-php-drupal
When you're creating a user profile page there is a built in mechanism for it. just create a user template file, user_profile.tpl.php.
When you use the built in mechanism you automatically get access to the $account object of the user you are browsing, including all user profile cck fields. You have the fields you are looking for without having to programmatically load the user.
I have a field called profile_bio and am able to spit out any mark up that is in without ever having to ask for the $account.
<?php if ($account->content[Profile][profile_bio]['#value']) print "<h3>Bio</h3>".$account->content[Profile][profile_bio]['#value']; ?>
I've tried themeing content profiles by displaying profile node fields through the userpage before and it always seems a little "hacky" to me. What I've grown quite fond of is simply going to the content profile settings page for that node type and setting the display to "Display the full content". This is fine and dandy except for the stupid markup like the node type name that content profile injects.
a solution for that is to add a preprocess function for the content profile template. one that will unset the $title and remove the node-type name that appears on the profile normally.
function mymodule_preprocess_content_profile_display_view(&$variables) {
if ($variables['type'] == 'nodetypename') {
unset($variables['title']);
}
}
A function similar to this should do the trick. Now to theme user profiles you can simply theme your profile nodes as normal.

Categories