WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Where do i put add_action (19 posts)

  1. bjarvis2785
    Member
    Posted 1 year ago #

    This is probably the most basic question you'll see today, but i just can't work out from the codex where i actually put the add_action() hook?
    I have created a function that makes a new directory on my server and also moves some files in to it.

    I want this to happen when i change a post status of a custom post type from pending review to 'published'.

    My hook is:
    add_action('pending_to_publish_portfolio', 'make_s3_dir');

    But where do i actually put this code?

    Any help appreciated.

  2. Hi bjarvis2785,

    To start, your action won't work because it's actually two different actions:

    add_action( 'pending_to_publish', 'make_s3_dir' );
    add_action( 'publish_portfolio', 'make_s3_dir' );

    You need to check for your post_type in the function.

    See wp_transition_post_status(), and look for the do_action() calls in the source.

    As for where to place your add_action calls, just call them right below your function. Something like this:

    function make_s3_dir() {
    	// do stuff
    }
    add_action( 'pending_to_publish', 'make_s3_dir' );
    add_action( 'publish_portfolio', 'make_s3_dir' );

    Hope that helps.

  3. Rajan V
    Member
    Posted 1 year ago #

    Hi all.,

    @bjarvis2785 : you put the code on function.php in theme file or create new plugin

    I have attach the sample code for plugin please refer this

    `<?php
    /*
    Plugin Name: Plugin Name
    Author: Your Name
    */
    // Hook for adding admin menus

    add_action('init', 'create_tbl');

    function create_tbl(){
    ....
    }
    ?>`

  4. bjarvis2785
    Member
    Posted 1 year ago #

    Thanks for the help so far guys and clearing up where to put the code.

    @drew - I'm afraid i'm not understanding how i utilise the post transition, or in fact these add_action hooks.

    My exact code in my themes 'functions.php' is as below:

    function make_s3_dir() {
    	mkdir('test_dir','0755');
    }
    add_action('pending_to_publish', 'make_s3_dir');
    add_action('publish_portfolio', 'make_s3_dir');

    I'm really new to all this as you have probably guessed, so apologies if i'm just being dumb :(

  5. bcworkz
    Member
    Posted 1 year ago #

    @bjarvis2785 - You appear to be using variable actions used by wp_transition_post_status(), linked to by Drew above. These can be tricky, as the status transition you think should occur may not occur.

    One thing to do to investigate is to hook 'transition_post_status' to see what statuses are actually being used for the event you want to trap. Insert this code with your other code, but leave it commented out for now, or WordPress will not work well.

    /*function bj_test($new, $old) {
       print_r("$old_to_$new");
       echo '<br>';
       print_r("$old_$new");
       die();
    }
    add_action('transition_post_status', 'bj_test', 10, 2);*/

    Navigate in WordPress to just before the event you wish to capture. Remove the comment symbols /* */ and save the file to the server. You can still use the WordPress editor as long as it's in a separate window from your test run. Or if you use a different method to edit files, that will work too.

    Now execute the event in WordPress you wish to capture and the above code will print the associated actions you can use, then die. We have to die or the printed content will often disappear before you can see it.

    To get WordPress back, replace the comment symbols, save the file again, then reload the page with the actions printed and all should be back to normal. Repeat for each event you want to capture.

    This may all seem like a hassle just to check a couple variables, but without a debugging framework, this one of the few tools available. Hopefully seeing a hook in action will help you understand the mechanics as well.

  6. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz - Thanks for the snippet of code, very useful.
    I ran it and it printed:

    inherit
    inherit

    So to me it seems there are two actions taking place (as per @drew jaynes advice) but not what i was expecting to see.
    I checked out the codex and it just says 'a revision or attachment. see get_children'
    Obviously because i'm taking it from 'pending' to 'published' it's seeing it as a revision i guess?

    I've looked at get_children and i just can't see how i can use the code available to me.
    All the tutorials online i come across make this look really easy and just simply use the "publish_{custom_post_type}" code as i tried above...

    Am i missing something really simple here?!

  7. bcworkz
    Member
    Posted 1 year ago #

    No, just need to get the right hook tag value for your situation. "inherit" is the value of $new, so apparently "published" is not what you need to use. Unfortunately, I passed along a code snippet without testing it. It has a stupid error, sorry :( Try this instead:

    /*function bj_test($new, $old) {
       print_r($old . '_to_' . $new);
       echo '<br>';
       print_r($old . '_' . $new);
       die();
    }
    add_action('transition_post_status', 'bj_test', 10, 2);*/

    This time I tested it :) It should now return the proper hook tag values. You will likely only need one or the other, as the both fire one after the other in wp_transition_post_status().

    When I did a similar test a while back, I'm pretty sure $new came back as "published". It now comes back as "inherit" on my system as well, so something has changed in status handling, which explains why the tutorials are not working for you.

    My revised code should return the right tag value, but your next hurdle could well be that the hook fires for other situations which you do not want your code to run, so you will need to add a conditional to ensure it only runs when it's supposed to.

    I'll be AFK for a while, but I'll check back in if I can to see how you get on. In the mean time I imagine others will be able to assist you if need be. Good Luck!

  8. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz - thanks once again for your help.
    I've run your new code, and now have:

    new_to_inherit
    new_inherit

    I have tested this on both a completely new post, and also when publishing an existing pending post. Both give the same above result.

    I am looking for this to work on a custom post type but did try it on the standard post type just in case and got the same results.

    When i google the inherit status all i get is that it's for post revisions, and also used for media attachments.
    There is in this case no media attached etc within the posts i'm creating.

    I'm stuck now.. i can't find anything of use when i google 'new_to_inherit'.

    surely this shouldn't be this difficult? :(

  9. bcworkz
    Member
    Posted 1 year ago #

    Sorry it's taking a while for me to get back to you, but that's the way it's going to be for a while. I promise I will not forget about you though.

    Thank you for re-running the script. Believe it or not, those are the add_action tags you need to use to trap whatever you did to initiate my script. You can use either one of these lines, you do not need both.

    add_action('new_to_inherit', 'make_s3_dir');
    add_action('new_inherit', 'make_s3_dir');

    This is instead of the pending_to_publish or publish_portfolio you were trying to use. These are the terms the system is using for your event. Since these actions fire on other publish actions, you'll need your code to check post type or something before doing anything to ensure your code only executes for the particular posts you want it to execute on.

    The reason you aren't finding anything with google (I think) is that the "inherit" status is fairly new. I think it used to be "publish", but I currently don't have time to try to research this, nor access to my test installation to figure out where it's coming from. For now, you'll just need to trust that the status the system is using is the status my script is returning.

    Go ahead and insert one of these new tags in your script and your function make_s3_dir() will be called. You may encounter other issues, but at least your script is called. It's still progress, albeit just one small step. Let us know how you get on with this. Good Luck.

  10. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz - Thanks once again for the reply. but you knew it wasn't going to be that easy, right?

    I've got the following code:

    function make_s3_dir() {
    	    mkdir('test_dir', '0755', true);
        }
        add_action('new_inherit', 'make_s3_dir');

    nice and simple... but alas, it doesn't create the directory...
    Just to make sure it's nothing else, i actually ran that function manually in a separate php file and the folder was created. So it points to the add_action() not being called.

    I don't mind waiting for your replies - nobody else seems to want to help, so i'm very grateful for your support on this so far.

  11. bcworkz
    Member
    Posted 1 year ago #

    I'm glad you're so patient. I'm afraid I'm half (or more) of the problem though. I can't seem to code correctly to save my life. I am truly sorry, not to mention quite embarrassed.

    The only correct action tag I gave you was the one you chose not to use. Just my luck, but it's good that my error did not slip through the cracks. This other tag, add_action('new_to_inherit', 'make_s3_dir'); will work for you. (but not the best choice, read on...) I had misremembered the form of the second hook which you did choose to use, and on review, this really is the right one to use because it will only fire for your specific post type, "portfolio". This is the correct form: add_action(inherit_portfolio', 'make_s3_dir');

    I'm confident this will work this time, but I was confident and wrong twice already, so I've knocked on wood and will not be too surprised if I'm wrong again, especially since I'm currently not able to even test my assertions. So good luck to both of us that we've finally moved beyond this silly step that shouldn't have been a big deal at all. Cheers!

  12. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz - thanks for the update.
    You know what i'm going to say now, right?

    neither of the above works :(
    This is really starting to bug me.. i don't understand how a pretty standard add_action() just refuses to work.

    Just a question - do i need to pass the post_id through the function?
    In some examples i see they pass post_id but in others they don't?

  13. bcworkz
    Member
    Posted 1 year ago #

    Well, I'm at a loss to explain now. new_to_inherit would work on my installation, though admittedly I haven't actually tested it. And I can't test right now anyway. I got the same two status values you did, and inspecting the wp_transition_post_status() source code indicates it would work. As far as inherit_portfolio goes, that will only work for your post type, which I don't have, so I can't test that without creating the same post type.

    Another thing you can do, though you shouldn't have to, is adapt the 'transition_post_status' action used in my test script. We know that action is firing or you would not get the new_to_inherit and erroneous new_inherit output. Try something like this:

    function bj_test($new, $old, $post) {
      if ('inherit' == $new && 'new' == $old && 'portfolio' == $post->post_type) {
        mkdir('test_dir','0755');
      }
      return;
    }
    add_action('transition_post_status', 'bj_test', 10, 3);

    Untested unfortunately. Less than efficient, but if it works, you can revisit the issue sometime later to make it more efficient. If it doesn't work, do a var_dump() of the 3 parameters and figure out where the mismatch is, because we KNOW this action is firing for you.

    About passing parameters, you should always do so with filter hooks, but with actions, nothing is typically done with a returned value so you don't need to pass parameters unless your hook needs the information. It's always a good idea to inspect the context of the initiating hook call to confirm what is passed and what if anything is done with any returned value. In your specific case, since you don't need the info, and the initiating function does nothing with a return value, there should be no reason to pass a parameter.

    That said, self doubt and inability to verify by simple testing make me say pass at least one parameter just to be safe. Which brings up another point. Anytime you have mysterious things happening, be sure to set WP_DEBUG in wp-config.php to true. There may be errors you don't know about unrelated to the task at hand preventing it from working, and this is the only way you'll discover it.

    I've jabbered on about what should be, and have not addressed what your issue is, because I have no clue at this point. It must be something silly that is not apparent. All I can suggest now is do some basic debugging to hunt down where things have gone wrong. This entails inserting var_dump($some_variable_name); die(); at various points to inspect the values of variables to ensure they are as expected and the code execution is actually reaching that point. You can even do this in WP core code if need be, just keep a clean backup of the original file before you muck around with core code. You might also need to wrap the var_dump(); die(); in a conditional if (){} block so code can execute normally up to the critical point.

    So good luck, you really need it now! I'll still check back here when I can if you want to keep me apprised of how things are going. Just because I cannot contribute anything constructive right now does not mean I'm giving up on you. Cheers.

  14. bcworkz
    Member
    Posted 1 year ago #

    @bjarvis2785
    I don't know if you'll still see this, it's been a while, but I did not forget about you. I've been swamped since I regained access to my test server, but I finally got around to testing your situation. I've found a few interesting things. First, my last suggested action has a syntax error. I can't believe how many screw ups I've had on this thread! This time it was a missing quote, so maybe you caught it. The correct form is:
    add_action('inherit_portfolio', 'make_s3_dir');

    I added my own custom post type, also called portfolio, and ran my transition_post_status test, publishing a portfolio post type that was pending review. This time it came back new_to_publish instead of new_to_inherit, which I still get with 'post' post types. So based on this, I added the following code:

    add_action('publish_portfolio', 'make_s3_dir');
    function make_s3_dir(){
    	mkdir('test_dir','0755');
    }

    Lo and behold, the test_dir was created! Though not where I expected. It ended up in the wp-admin folder. Not sure why, but that's what happened. Probably because the publish POST request went to a file there.

    If you were getting a new_to_inherit test result for your situation, the inherit_portfolio action would still be correct for you to use. I used publish_portfolio because I got new_to_publish as a test result.

    Bottom line is despite several stupid errors on my part, there is nothing wrong with the code we are discussing, it does work as expected. If you cannot add a directory, the reason for failure lies elsewhere, the code here is fine. I hope this helps somehow.

  15. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz
    You, my friend are amazing!
    firstly, i can't believe you came back to offer more help after all this time! Thank you so much.

    Secondly, i've got it working :)
    The code snippet you posted in your last post did the trick, so it turns out this problem could've been solved a while ago had i been looking in the right place for the created directory.
    I didn't think to look in the wp-admin folder.

    Anyway, thank you once again!

  16. bjarvis2785
    Member
    Posted 1 year ago #

    @bcworkz
    Following on from my earlier reply.
    Although my function is now triggering when using add_action, it's also triggering when i don't want it to.

    I only want it to trigger when a post changes from pending to published.

    I am using publish_portfolio in the add_action.
    After some testing, it seems this triggers when you publish the post and also when you update the post if it's already published.
    So i tried changing it to pending_to_publish_portfolio which didn't work.
    I've also tried inherit_to_publish_portfolio and pending_to_inherit_portfolio and also inherit_portfolio - none of those worked at all.

    So it seems the only one that does work for me is the original publish_portfolio.
    Is there a way i can use but use another check to see if it's published for the first time or whether it's just an update?

    I did try using a statement along the lines of if ($post_status == 'published') but i'm not sure my syntax is/was correct.

    Any help with this one?

  17. bcworkz
    Member
    Posted 1 year ago #

    Heh, it was too good to be true that this was resolved, eh? :)

    Try hooking 'new_to_publish' or 'new_to_inherit' depending on the test script results and what was sort of working previously, which I guess is the former, so try that first.

    The problem will be this could trigger for all post types (except the 'inherit' ones), fortunately your action callback is passed the $post object, so just use a conditional like
    if ('portfolio' == $post->post_type) {//do stuff...}

    I think this should do it, but I'm not holding my breath. :/

  18. bjarvis2785
    Member
    Posted 1 year ago #

    Ok, so i think i've got it working now...

    i've resorted to using pending_to_publish and then checking the post_type as per your suggestion.

    function test_func() {
    	global $post;
    	if ('portfolio' == $post->post_type) {
       	echo 'success';
       	die;
       	}
       }
       add_action('pending_to_publish', 'test_func');

    I had to add in the global $post but once i did that it seems to be working as expected :)

    Thanks once again!

  19. bcworkz
    Member
    Posted 1 year ago #

    I think there is a risk the global could contain the wrong $post object when the action is triggered. You need to use the passed $post object to be assured it is the correct post. I see you are missing some useful knowledge here about passing hook parameters. Prepare for WP Hook Lesson 3! (skip down to the *** part below if you're in a hurry right now)

    Most filter hooks and several action hooks will pass useful information to your callback function to use as desired. Filter hooks actually expect the first parameter returned back to them, altered by your filter function as desired.

    When only one parameter is passed, you don't need to do anything special to hook on, you've done this already. To know how many parameters are passed, you need to locate the initiating function in source code to see what it is passing along. To get more than one parameter passed to your callback, you need to provide 2 more parameters in the add_filter() or add_action() function. The priority and the number of parameters to pass. The priority defaults to 10, it's normally fine to use the default.

    For example, earlier I used

    add_action('transition_post_status', 'bj_test', 10, 2);
    function bj_test($new, $old) {
    //more stuff...}

    My function was passed 2 parameters, $old and $new. You can see how I specified I wanted two parameters passed in add_action(), and how my function bj_test() accepted the parameters inside of the function parenthesis. As it happens, 'pending_to_publish' action only passes one parameter, $post, how useful! I mentioned the additional parameter variation for completeness, I hope you find it useful and are not bored to tears.

    Anyway, if you accept the $post passed by the hook instead of using the global, you are assured of being passed the correct $post object.

    *** skip to here if you're in a hurry

    Specify you want to use the $post value passed instead of the global like so:

    function test_func($post) {
    	if ('portfolio' == $post->post_type) {
       	echo 'success';
       	die;
       	}
       }
       add_action('pending_to_publish', 'test_func');

Topic Closed

This topic has been closed to new replies.

About this Topic