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.
Related
I really need your help with this matter. I'm looking for a solution for about 3 months now, but really the Blogger API is not easy to deal with because Blogger don't even provide examples.
I can create and publish new posts with PHP script and I have done all things, but I can't set the Post's description, permalink, or even making the new post as draft.
The following is a piece of my code that creating the post.
<?php
$mypost = new Google_Post();
$mypost->setTitle('My Post Title');
$mypost->setContent('This is My Content');
$mypost->setLabels( array( 'News','Weather', 'Media' ) );
$mypost->setCustomMetaData('My_CUSTOM_META_DATA' . time()); // Nothing changed
$mypost->setcustomMetaData('This is the description for you'); //Nothing Changed
$mypost->setDescription('New Description'); // Nothing Changed
$mypost->setUrl('testseturl'); // Nothing Changed
$mypost->setPublished('2021-08-27T23:07:00-07:00'); // Worked as Schedule post
$data = $blogger->posts->insert('My BlogID', $mypost);
echo "<pre>";
var_dump($data);
echo "</pre>";
?>
As you can see I can't set the permalink and I tried several thing such as adding the full URL, and also adding only the custom permalink text + html, but I failed.
I tried also the description several times, but every time I found the description's post empty.
Also I can' set the post as Draft and I have to do this manually from the blog itself.
Blogger doesn't provide any help docs for PHP, and the new Beta client library on github is for all Google products and I wasn't able to use it. I use the library Google API PHP Client 0.6.7 found here although it's deprecated.
The only topic I found in this blog, and it's the same code that I use, but he didn't mentioned anything about permalink, draft, or description.
Please help me as you can.
Thanks.
permalink
Unfortunately there is no way to set custom permalink to the posts using Blogger api, even the official "Try this API" tool don't have this feature, your code is fine it's just Blogger don't support it.
custom description
I don't think there is a way to add custom description as well, setDescription is not a valid method, you can check all the supported methods here
draft post
to create a post draft you can do it like this
$optParams = array('isDraft' => true);
$data = $blogger->posts->insert('My BlogID', $mypost, $optParams);
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
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);
Whenever a user posts a comment, I'd like to basically have a copy of the post sent to another database for a separate site. The database part is simple, but I can't seem to find the right action hook for this. (I did my testing with a simple echo statement, a failure being it not displaying at all) 'comment_save_pre' would only work when updating a comment, 'wp_set_comment_status' only works when the comment is approved, and 'comment_post' didn't seem to work at all. Does the hook exist?
add_action('...?...', 'on_comment_post');
function on_comment_post($comment){
echo "Test";
}
You can use comment_post :
Runs just after a comment is saved in the database. Action function
arguments: comment ID, approval status ("spam", or 0/1 for
disapproved/approved).
I've been asked to fix a problem on a wordpress site. The problem is caused by the fact posts should of been used instead of pages. However the site is up and running and quickest option would be to fix the problem using a hack of sorts.
The site has an events section, each event is a page (this is the issue, should really be a post). In order to have upcoming and past events the post date is used, therefore upcoming events has a post status of 'future'.
There's are list page of events which shows them fine by using the correct query_post(). Although the problem arises when you click through to actual event (which is a future page). If your logged in as an Admin then the page shows but if your not logged in you get a 404 page.
Now if they where posts then the "The Future is Now!" plugin would solve this problem. I have a feeling the only way round the problem is to rewrite part of core Wordpress files.
Any advice would be great, I have a lot of experience with Wordpress so even if you can point me in the right direction.
Cheers,
Jason
[Update]
Thanks maiorano84 for your detailed response. In the long run I intend to move them to posts but in the meantime they've requested we fix it asap without changing any urls (today they sent out a mass email with a list of events without checking any links)
Your solution of including post_status future doesn't work in this case as wordpress doesn't get to the stage of loading the template. Something in wordpress core stops it from getting that far. Ideally if they was a hook I could use to override this behavior in the meantime that would be excellent but if it comes to it I will temporarily edit the core files.
[Update 2]
I now know the two functions that need editing or use a hook that relates to them.
First of we is_404() which needs changed to not add future pages as 404
Second we have is_page() need to return true if a page is future
[Update 3]
I've found how to do this in the core. If you go to wp-includes/query.php line 2682. Copy this in instead of the old function it works correct. If you have a better way please let me know. Thanks.
/** Future Pages **/
// Check post status to determine if post should be displayed.
if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
$status = get_post_status($this->posts[0]);
$post_status_obj = get_post_status_object($status);;
if ( !$post_status_obj->public ) {
if ( $post_status_obj->protected ) {
$this->is_preview = true;
print_r($status);
if ( 'draft' != $status ) {
$this->posts[0]->post_date = current_time('mysql');
} else {
$this->posts = array();
}
} elseif ( $post_status_obj->private ) {
if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
$this->posts = array();
} else {
$this->posts = array();
}
}
/** END **/
You can actually add a post_status parameter of 'future' to your page queries. You REALLY shouldn't be modifying your core files in order to do what you want. So on your page.php and archive.php templates (or other relevant templates that's controlling your Event display), you can do something like this:
<?php
$params = array('posts_per_page'=>-1, 'post_status'=>'publish,future');
$query = new WP_Query($params);
if($query->have_posts()) : while($query->have_posts()) : $query->the_post();
?>
<!-- YOUR PAGE HTML HERE -->
<?php
endwhile;endif;
wp_reset_postdata();
?>
This is an oversimplification, but using the correct queries in the corresponding files will allow you to display your pages however you like.
More information here: http://codex.wordpress.org/Class_Reference/WP_Query
Another thing worth considering, and I realize that this wasn't a part of your question, but may very well solve your issue:
Why not create a subdomain on your client's server where you can work on fixing everything without interrupting the user experience? You can easily either import the existing database into your development environment, and make all the changes you need without affecting the live version.
Food for thought. My advice would be to nip this in the bud, and convert the pages over to posts as soon as possible, otherwise the website will turn into a giant mess very quickly, but that's your call.
Hope this helps.
UPDATE:
I would still advise against altering the core files, but if it's a last resort until everything gets fixed, then have at it. Here's is a "WP Friendly" solution I think might help:
add_action('wp','future_redirect', 0);
function future_redirect($WP_Object)
{
$page = is_page() ? get_page(get_the_ID()) : false;
if($page && $page->post_status == 'future')
{
wp_redirect(/*YOUR REDIRECT URL*/);
exit();
}
return $WP_Object;
}