Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] 2.x build() method breaks polymorphism due to incorrect return type declaration #2807

Closed
mindfullsilence opened this issue Sep 24, 2023 · 4 comments · Fixed by #2976
Closed

Comments

@mindfullsilence
Copy link

mindfullsilence commented Sep 24, 2023

Expected Behavior

The build() methods would declare the return type as the concrete class - static instead of self.

Actual behavior

Timber entity classes declare their return type as self rather than static, even though they return an instance of the calling class.

namespace Timber;
//...
use WP_Post;

class Post extends CoreEntity implements DatedInterface, Setupableclass {
  //...

  // declared return type is "self", but should be "static"
  public static function build(WP_Post $wp_post): self
  {
    $post = new static();

    //...
    return $post;
  }
}
class MyPost extends \Timber\Post {
    
  public static function build(WP_Post $wp_post): self
  {
    $post = parent::build($wp_post);

    $post->initialize(); // works, but breaks code inspection tools

    return $post;
  }

  public function initialize() {
    // do custom stuff here
  }

}

Steps to reproduce behavior

  1. Extend a Timber entity, and add it to the classmap
  2. Override the build() method to run additional bootup code, using parent::build($wp_post)
  3. Call a child class method in the childs' build() method from the instance returned by the parent build() method

The return type declared will issue warnings from code inspectors because they expect the return type to be an instance of the child class (static), but the return type declared in the Timber class is self, which is inaccurate to what is actually returned. The return type should be static.

Notes

This doesn't throw an error, because what's actually returned is an extension of Timber\Post, so self technically works but is wrong. The return type declared for the build methods should be static since that's what they instantiate via $post = new static(). PHPStorm (and I'm sure a lot of other code inspection tools) warn about polymorphic calls to child methods not existing because parent return type represents the parent class, which doesn't have the added methods in its signature.

What version of Timber are you using?

2.0rc1

What version of WordPress are you using?

No response

What version of PHP are you using?

8.1

How did you install Timber?

Installed or updated Timber through Composer

@Levdbas
Copy link
Member

Levdbas commented Sep 28, 2023

Thanks for bringing this up @mindfullsilence ! Would you like to make a PR for this against the 2.0 branch?

@nlemoine
Copy link
Member

Thing is, static return type has been introduced in PHP 8.0. Unfortunately, we're still supporting PHP 7.4.

@mindfullsilence
Copy link
Author

mindfullsilence commented Sep 30, 2023

Since you still support 7.4, I'd recommend leaving this the way it is for now. Is a bump to >=8.0 constraint planned for a future release? 7.4 was sort of a weird in-between stage of php where strict-typing was only partially implemented.

@gchtr
Copy link
Member

gchtr commented Oct 10, 2023

Let’s move this to a future release. I think we should leave PHP 7.4 support to ease the transition to Timber 2.0. But for a future release, we’ll quickly bump to 8.0 or even a higher PHP version.

@Levdbas Levdbas linked a pull request Apr 26, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants