im try to use wp_mail when a post is (created|updated) using the publish_post action
strange thing is it works fine when im editing and existing post, ie all the $post object can be retrieved using:
$post = get_post($post_id);
but when i use it on a new post it doesnt have the post object???
i can get the vars using the global $_POST but that bloats the code so much, checking if it there or now.
ive tried the other actions as well (save_post|wp_insert_post|publish_post-type)
has anyone ever had this?
You shall add a listener to the publish_post method:
add_action('publish_post','do_whatever');
function do_whatever(){
//what do you do
}
OR if you trying to code it in an OO way, you can:
include 'MyObj.php';
$my_obj = new MyObj();
add_action('publish_post', array($my_obj, 'do_whatever'));
//in your object php
class MyObj{
function do_whatever(){
//what do you do
}
}
NOTE: this setup will make the do_whatever call whenever you post is saved/auto saved. you have to do extra coding for your own purpuse.
It will be clear for us to know what are you trying to achieve in order to suggest you more information.
Related
I am using wordpress.
I need to run a function (send a email) when a scheduled post is automatically posted.
What hook/function should I use ?
Use post status transition hooks
function scheduled_post_published($object)
{
// whatever it is you need to do
}
add_action('future_to_publish', 'scheduled_post_published');
I think you need to use the hook transition_post_status, from the documentation:
transition_post_status is a generic action that is called every time a post changes status.
And on https://wordpress.stackexchange.com/a/100657 I found piece of code that can you use as inspiration.
Here is how I've implemented it:
add_action( 'delete_post', array( 'MyClassName', 'delete' ) );
In the delete function I was using a $wpdb->insert command to see whether the function gets called. But I see that the $wpdb->insert command is called twice (inserts two rows in my table). Any ideas as to why something like this might happen?
I've also attempted to use the before_delete_post hook since it doesn't really make a difference to me but I get the same outcome.
EDIT:
It seems as though the delete function is called for each entry in the wp_posts table for some reason. So if the post has 3 revisions, the delete function will be called 4 times (the original post + 3 revisions). This is really weird behavior.
I found my solution.
The function you hook into delete_post (or probably any other similar hook) executes as many times as needed. Considering delete_post needs to delete the post and all of its revisions, it will always run more than once. In order to avoid having your function execute each time WordPress deletes a record from the database you can use did_action( $hook ). This function returns the number of times the hook executed. With this in consideration, we can fix our multiple-executions problem by placing this condition into our function:
if (did_action('delete_post') === 1)
{
// execute code here
}
I found something similar here: http://wordpress.org/support/topic/publish_post-hook-multiple-firing
Basically I am using the edit hook in wordpress to add some data to a table, and the function gets called twice. The first time it goes with its default values, the second time it has the actual data.
Anyone come up with this issue? Is it really an issue or I am missing something?
Action:
add_action('edit_post', 'my_func');
Function:
function my_func() {
if(!wp_is_post_revision($post_ID)) {
// Code to get $_POST data, omitted
// Call to the database here, omitted
}
Thanks.
edit_post is triggered when you edit AND update the post(even when a comment is added to that post) . What you need is the publish_post hook. Read this page for more info.
I have developed wordpress for days,but I have found no way to these like:add_action,add_filter,user_can, I don't know what are the functions they refere to.
worse still,I don't know the parameter,today I want add a column to user list table admin panel,I fortunatelly found a tutorial, here is the code
add_filter( 'manage_users_columns', 'add_user_column');
function add_user_column( $columns){
$columns['available_stickers'] = __('Stickers Available', 'available_stickers');
return $columns;
}
add_filter('manage_users_custom_column', 'add_user_column_value', 10, 3);
function add_user_column_value( $value, $column_name, $user_id ){
if ( 'available_sticker' == $column_name)
$value = get_user_meta($user_id,"available_stickers",true);
return $value;
}
Even thought I made it, but I don't know where the parameter manage_users_columns comes or why I should use manage_users_columns but not other code? Puzzled
and also they have matched code like apply_filter etc.
some one can help me out of the maze,oops!
WordPress is beautifully designed because most of the actions it does are not executed directly, but through what are called actions and filters. This gives you, the developer, a possibility to hook onto any of these operations. Hooking means you can squeeze your own logic right in the middle of WP's logic, in a very clean way, only by declaring that you want things to be done where the corresponding hooks are used. More precisely:
Actions
So, for example, when a post is saved, WordPress does not just save the post, it does it by executing this line:
do_action( 'save_post', $post_ID, $post );
This is a way to give a name to this action (save_post). That means two things :
1) you can execute the exact same action by using the same line of code somewhere else.
2) you can add your own logic to be executed during this action. How? just by "adding" your custom functions to the action, like this :
add_action('save_post', 'name_of_the_function_you_want_to_execute_when_post_is_saved');
So 'save_post' is the name of the hook, add_action gives you the possibility to add your own function to the action for this hook and do_action actually executes the action.
Filters
Filters are similar to actions, but instead of being used when executing a command, they are used to treat a value, an object, a string or some text (when "filtering" it). Again, instead of just manipulating objects and strings in such a way that you would have no other possibility than dive into the core code to access it, WordPress cleverly does many of its "filtering" operations with a special action called apply_filters(). This gives you the possibility, like for actions, to actually add your own filters to the filters already applied. So when showing the content of a post, WP would execute :
apply_filters('the_content', $post->post_content);
The name of the hook is the_content. If you use :
add_filter('the_content', 'your_function_to_execute_to_further_filter_content');
you can have a function named your_function_to_execute_to_further_filter_content()that can take the content as a parameter and return the filtered version of it after whatever treatment you wish to apply to it. Then this treatment will get applied anywhere in WP where the hook the_content is used to execute these filters (including WP default ones, plug-ins filters that were added to the same hook, and your own).
So here, you are using these hooks so you can interfere with WP operations without messing WP core code. You declare the extra operations you wish to execute and you let WP aware of this. WP will then have the courtesy to execute your functions everytime the corresponding hook action or filter is being executed.
I would like to limit the use of some url's. Let's say node/add and node/7 (just random examples). I'm thinking the best way to do this is to use the user_access function.
But as we are used to it, the Drupal documentation doesn't help much. When I just use the function, I get the message the function is already in use. So my best guess is to use this existing function with my own arguments in my custom function in my custom module.
But in this way I need to catch the page before loading it. Or I'm I missing something here?
EDIT:
I've set this
global $user;
$items['node/add/%']['access callback'] = array('_mymodule_node_access');
$items['node/add/%']['access arguments'] = array(0,2, $user);
But for some reason, Drupal isn't picking up the % card for all types. It's just working for one type (script). Other terms like page or fiche aren't getting picked up... % is a Drupal wildcard right?
EDIT:
I just found out there are already some paths in the database. How can I overwrite them? What I need is one selector which can select all four content types (fiche, page, script and news-item).
The way to define a particular access function for a path is to set the access callback for the path's menu item in hook_menu(). This is slightly different for existing paths, in that you need to implement hook_menu_alter() to edit the existing access callback for that path:
function mymodule_menu_alter(&$items) {
$items['node/add']['access callback'] = 'mymodule_node_add_access_callback';
}
function mymodule_node_add_access_callback() {
// return TRUE to allow access, FALSE to deny
}
This gets a bit more fun when we're talking about node pages as their menu items is defined using a wildcard node/%. This means that using hook_menu_alter() you can only change the access callback for all nodes.
Fortunately Drupal has a hook_node_access hook to come to the rescue:
function mymodule_node_access($node, $op, $account) {
$restricted_nids = array(7, 10, 12);
if (in_array($node->nid, $restricted_nids) && $op == 'view') {
if ($some_condition_is_true) {
return NODE_ACCESS_ALLOW;
}
return NODE_ACCESS_DENY;
}
return NODE_ACCESS_IGNORE;
}
Hope that helps
EDIT
If that all seems like a bit much hassle you might get some joy installing the Path Access module, I think it has the functionality you're after.
ANOTHER EDIT
I think the reason overriding the wildcard isn't working in this case is because the node module explicitly defines a path for each node type, e.g. node/add/page, node/add/article, etc. Because Drupal will take an exact match (node/add/page) over a wildcard match (node/add/%) you're actually overriding the wrong menu item.
Try specifying the path explicitly in your hook_menu_alter() function (note that the access callback should be a string and not an array as you currently have):
$items['node/add/page']['access callback'] = '_mymodule_node_access';
$items['node/add/page']['access arguments'] = array(0,2, $user);
It's also worth noting that the $user object you're passing will always be the user object of the logged in user who cleared Drupal's caches (since menu items are rebuilt when the cache is rebuilt). If you're looking to pass the current logged in user (i.e. the one logged in at the time the page is accessed) that's a different thing altogether...I'd advise asking another question on it as it can be a tricky bugger and you want to get as much input as possible from people on here.