• ResolvedPlugin Contributor IAmAdamTaylor

    (@ad_taylor)


    Hi,

    The current version of the plugin has a bug in the ProtectTheChildren_Helpers::isEnabled() function that causes the code to target the wrong post object when certain conditions are met.

    The error is most visible under these conditions:

    1. Create a password protected page, enable Protect the Children on it and then set the Parent for this new page to an existing page.
    2. Ensure WP_DEBUG is enabled and output is visible
    3. View the front end page
    4. Observe a PHP Notice is shown: <b>Notice</b>: Trying to get property ‘ID’ of non-object in <b>/Users/adamtaylor/Sites/whs-wp/wp-content/plugins/protect-the-children/_inc/helpers.php</b> on line <b>57</b>

    This is caused because the plugin checks the new pages ancestors and does not find a password protected ancestor among them.

    Tracking this error back, it appears to be because a conditional statement is allowed to fall through in the isEnabled function mentioned earlier.

    In that function the passed $post argument is handled differently if an array of post IDs is passed, i.e. the return value from get_post_ancestors(). However, if that check fails to find a password protected ancestor, the foreach loop never returns a value and therefore the code falls through to the second if statement (line 39) that cannot handle being passed an array.

    There are 2 possible fixes for this issue.

    You can either add a ‘return false;’ after the foreach loop finishes, or use an elseif on line 39 to ensure it is only executed for non-array arguments.

    I’ve prepared a patch (I hope correctly!) adding the ‘return false;’ line which can be seen here:
    Patch ataylor-isEnabled

    Thanks,
    Adam

Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Author Matt Miller

    (@millermedianow)

    Thank you for this detailed post. We are looking into this and will let you know if we need any additional information. Thanks!

    Plugin Author Matt Miller

    (@millermedianow)

    Hi there, we cannot seem to reproduce this issue. Can you update to the latest version of the plugin (1.3.9) that we just released today and let us know if the issue persists? Thanks!

    Plugin Contributor IAmAdamTaylor

    (@ad_taylor)

    Hi,

    Thanks for the reply. I’ve updated to the latest version of the plugin and the issue still persists. I’ll try and give a step by step way to recreate the issue on a fresh install:

    1. After setting up WordPress, install the plugin (1.3.9)
    2. Go to Pages and create a new page named ‘Top Level Page’ (ID:7)
    3. Create another page named PTC Page (ID:9) and set its parent to Top Level Page
    4. Create one final page named PTC Child Page (ID:11) and set its parent to PTC Page
    5. Edit PTC Page and add password protection and turn on PTC

    With a fresh install, you will also need to add a debug statement to reveal the error. I was getting a PHP Warning because I had deleted the ‘Hello world!’ post (ID:1) that WordPress automatically creates for you.

    Add these debug statements to the _inc/helpers.php file

    
    static function processPosts($post)
        {
            echo '<pre>'; 
            var_dump( 'Param passed: ', $post ); 
            echo '</pre>';
            
            if ( is_int($post) or !is_object($post) )
                $post = get_post($post);
    
            echo '<pre>'; 
            var_dump( 'After get_post: ', $post ); 
            echo '</pre>';
    
            if ( !self::isPasswordProtected($post) )
                return false;
    
            if ( get_post_meta($post->ID, 'protect_children', true)  )
                return $post;
    
            return false;
        }
    

    Now view the PTC Page on the front-end. You will see on the first pass, which is the foreach loop, it checks Top Level Page and correctly detects that this is not a password protected page.

    This is when it falls through to the second part of the isEnabled function which cannot correctly handle arrays. The ‘Param passed’ log shows the post parent IDs as an array and the ‘After get_post’ log shows that the post has been incorrectly found as the ‘Hello world!’ post ID:1.

    For anyone who has deleted the ‘Hello world!’ post, as I had, the get_post call will return null instead, leading to the following line get_post_meta($post->ID, ... to cause a PHP Warning because $post is no longer an object.

    As mentioned before, this can be mitigated by not letting the loop fall through to the second part of the isEnabled check.

    • This reply was modified 2 years, 10 months ago by IAmAdamTaylor.
    Plugin Author Matt Miller

    (@millermedianow)

    Hi @ad_taylor , thanks for the details; we were able to recreate this and fix it. In the code we updated it to check if the $post variable is an array and if so, loop through it and check all the items of the array (even if it’s just one). We have updated the plugin to Version 1.4.0 and have added you as a contributor. Thanks for the help and let us know if that resolves the issue on your end!

    Plugin Contributor IAmAdamTaylor

    (@ad_taylor)

    Hi @millermedianow

    Brilliant, that’s resolved the issue ??

    Thanks for adding me as a contributor too!

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘isEnabled check does not accurately target correct post object’ is closed to new replies.