When a Page Method is declared in a plugin, PHP `method_exists` returns false if used to detect the method in a hook

Hi!

I’m making a plugin to generate my OG images, adapted from @rasteiner’s (very helpful) code from this message: OpenGraph image generation when page is edited, not when image url is requested - #2 by rasteiner.

I’ve noticed that when defining a Page Method in a plugin, and then checking if the method exists for the page in a hook defined in the same plugin, the method_exists check returnss false.

See code:

Kirby::plugin('joachim/opengraph-images', [
  'pageMethods' => [
    //Generate the OpenGraph image
    'createOgImage' => function () {
       …
    },
  ],
  'hooks' => [
    'page.update:after' => function (Kirby\Cms\Page $newPage) {
      // if the page has a createOgImage() method, call it.
      if(method_exists($newPage, 'createOgImage')) {
        $newPage->createOgImage();
      }
    },
  ],
]);

On the other hand, when removing the check, the method is exectuted when the hook fires, so it seems to exist after all?

Instead of using this check I ended up using a null safe operator, like this: $newPage?->createOgImage();

Anyways, I don’t know if it a bug or a bad understanding of how things should work, but I thought it could help to document it :slight_smile:

Have a great day!


Joachim

Given that you now ended up with something completely different, I wonder what you are trying to achieve.

The null-safe operator is pretty useless here, because $newPage is definitely a page object in this case, so why use it?

Also, since you created the method and you know it exists, there is also no need to check if the method exists. This would be different if you created the method only in a single Page model but not in another. So the method might not be defined in some Page types.

The pageMethods() extension, however, does not extend Kirby’s Page class, but add the methods to the static $methods array, which is checked within the magic _call() method, which also makes sure that field in content resolved when called as methods. So you can check for $page->hasMethod('createOgImage')