0

I've added a wp_login action and it's getting executed. Then within that function, I'm adding a filter to the_content so that a script gets inserted upon certain conditions but it's not getting executed. The filter within the wp_login action is:

add_filter( 'the_content', 'my_function', 10, 1 );

If I move that filter to outside wp_login it works.

I've also tried adding actions 'wp_loaded' and 'wp_enqueue_scripts' but no go either.

Do the actions get cleared at some stage after wp_login?

6
  • 1
    Why would you want to add the_content filter inside wp_login filter? The wp_login fires after successful user login, wp_content filters the generated WP content. If you want to limit your changes to wp_content filter for logged in users, use is_user_logged_in() condition inside the content filter instead (or specific user ID conditions). Commented Jul 11, 2022 at 7:42
  • The reason is that I only want to change the content on the page being loaded after the user logs in. Not after that page is loaded for the 2nd or any subsequent time, just the very first time upon login.
    – Vic
    Commented Jul 11, 2022 at 7:53
  • I understand, maybe this approach would help you. Commented Jul 11, 2022 at 7:56
  • The issue is why is the the_content filter or the wp_loaded action not getting executed when set within the wp_login action hook?
    – Vic
    Commented Jul 11, 2022 at 8:06
  • Because that is not the correct approach. Your code gets executed after the user is successfully logged in (wp_login filter), but only then the desired page gets loaded and the content is generated. Your the_content filter callback was however executed on the 'previous' page, not the current one. The approach in the link above should suit your case as well. Commented Jul 11, 2022 at 8:29

2 Answers 2

2

You've misunderstood how hooks, and PHP, work.

Hooks are not persistent. Each time you visit a page in WordPress the PHP scripts that comprise WordPress all get run. Every time. This includes plugins and the theme's the functions.php file. So when you run add_action() that queues up a callback function to run whenever the corresponding do_action() is run. Once everything has run and the page has rendered nothing is remembered. The only persistent information is whatever gets stored in the database, and hook callbacks are not stored in the database.

So, if you try to run add_filter( 'the_content', 'my_function', 10, 1 ); on wp_login, the my_function() callback will only be applied to the_content if the the_content is displayed for that single request where the user is logged in. This is almost certainly never going to happen because users are typically redirected after being logged in, and that redirect is a separate request.

What you are actually trying to do is filter the_content if the current user is logged in. The proper way to do that is to check if the user is logged in inside my_function() and to add your filter for every request:

function my_function( $content ) {
    if ( is_user_logged_in() ) {
        // Do something with $content.
    }

    return $content;
}
add_filter( 'the_content', 'my_function' );

Note that add_filter() is at the 'top level', and not inside another hook. It will run on every request, but the content will only be modified if the user is logged in. Also note that we used is_user_logged_in() inside the callback function, instead of around add_filter(). This is because when add_filter() will be run it hasn't been determined if the user is logged in or not yet.

1
  • Ok, got it. Both you and Kristián made me realise I incorrectly assumed after login that I was already on the page being loaded, but of course not, it's still on login! A better solution I worked out was to use add_filter( 'login_redirect', 'site_login_redirect', 10, 3 ); and then add a get parameter to the page I want to redirect to, then I can read this value and add the_content. Thanks so much for your reply, it was very thorough!
    – Vic
    Commented Jul 11, 2022 at 11:24
1

I've read your question and comments once again and I finally get what you are trying to achieve here. Calling the_content filter from inside wp_login callback will not work (as explained in Jacob's answer in detail).

Solution in my link I posted as a comment above will also not work, it's meant for a different scenario.

Your best bet would be to assign custom user_meta value to each user, that would prevent second and any other subsequent runs of your code. Here's a simple example:

function custom_the_content( $content ) {

    // Only for logged in users
    if( is_user_logged_in() ) {

        // Get user ID
        $user_id = get_current_user_id();

        // Check if the content was already filtered for this user (if yes, do nothing)
        if( get_user_meta($user_id, 'content_filtered', true) ) {
            return;
        }

        // Filter the content (do anything)
        // ...

        // Set the user meta for subsequent checks
        update_user_meta($user_id, 'content_filtered', 'yes');
    }
}
add_filter('the_content', 'custom_the_content');

Add your code (any changes to the_content) instead of the three dots in my example. The code should be altered only once for each logged in user.

EDIT: If you need to change the content every time the user logs in, you can just delete this custom user meta with the wp_login action (or you can use cookies, session variables or WordPress transients instead of database meta data, your choice).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.