2

I am initializing a class where the constructor requires a WP_Post object. The object I would like to pass comes from get_queried_object() which could return almost anything. I am using is_a() to make sure I have the right type, which "works", but my IDE does not recognize that I have constrained the type.

Is there a way to make it clear to the IDE that I have done my due diligence? I don't want to get in the habit of ignoring my IDE. It has been so nice to me in the past and saved me from so many mistakes. :)

$queried_object = get_queried_object();

if ( is_singular() && is_a( $queried_object, 'WP_Post' ) ) {
    // Initialize class that requires WP_Post object.
    $class = new ClassThatOnlyAcceptsPostObject( $queried_object );

    // ...
}
2
  • If is_singular() is true, then the queried object must be a post object. Feb 27, 2020 at 0:55
  • Thanks @JacobPeattie that is a good point, however my IDE is not so easily convinced. It doesn't even trust is_a(). Thankfully it does trust instanceof. Feb 27, 2020 at 13:05

2 Answers 2

2

In addition to what Tom already said, using instanceof has worked quite well for me. (Actually never heard of is_a() before.)

if (is_singular() && $queried_object instanceof \WP_Post) {
    // do something
}

Both PHPStan and my IDE know that after this check, $queried_object is an instance of the WP_Post class.

1
  • 1
    Thanks! Turns out a simple instanceof was exactly what I needed. Sidenote: is_a() does a similar thing and matches parent class too, but at considerable cost. Feb 27, 2020 at 12:50
2

No, you can't change what a function returns without modifying it.

You can, however, do several other things:

  • Provide type hints on your constructor's arguments, your IDE and PHP will then know that a \WP_Post object is required and that nothing else will do
  • Use instanceof instead of is_a, which will be picked up by the IDE
  • Perform checks on the return values of the functions and handle their failures
  • Convert non-post object return values into something the class will accept
  • Refactor things so that you never end up in the situation where a WP_Term or some other kind of object is returned
  • Wrap the function in another function that returns either a post or an error value if it's not a post/valid

More importantly, I have to question the value of an object named PostContent, and whether it's using classes for the sake of using classes. I don't see what the object can do to a posts content that can't be achieved using standard templates and filters on the_content. By rolling your own, you give up a lot of the advantages, filters, and plugin compatibility you get by just using standard APIs and a standard post loop. If this classes job is to process markdown or insert ads, then it needs a more specific name, and can just be created as and when it's needed

2
  • Thanks for the note on the class name :). I just threw in the first thing that popped into my head as a demo. The classes I am actually using are far more useful than this one. Feb 26, 2020 at 17:54
  • I edited my class name to avoid confusion. Thanks! Feb 27, 2020 at 13:07

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.