Problem with hook & function inside class

General Kirby,
here’s my problem:

In the root of a plugin I’m writing, say myplugin.php, I’m going like this:

<?php

// myplugin.php

// Composer autoload
require_once  __DIR__ . DS . 'vendor' . DS . 'autoload.php';

// Loading my library
require_once __DIR__ . DS . 'lib' . DS . 'lib.php';

function init() {
  return new Kirby\Plugins\MyPlugin\MyClass;
}

Alright, but there’s a problem: In this file plugin/lib/lib.php, I’m calling a hook on panel.file.upload, eg creating PDF from certain documents. So I’m like

<?php

// lib/lib.php

namespace Kirby\Plugins\MyPlugin;

use C;
use PDFLib;
// ...

kirby()->hook('panel.file.upload', 'createPDF');

class MyClass {
  private $someValue;

  public function __construct() {
    $this->someValue = c::get('plugin.myplugin', 'some-default');
  }

  // ...

  public function createPDF($file) {

    try {
      // Checking file type since only images are processed
      if ($file->type() == 'document') {
        // do stuff

      }
    } catch (Exception $e) {
      return response::error($e->getMessage());
    }
  }
}

Now, whenever I upload stuff, I get this error: Function createPDF() does not exist - what can I possibly do to debug this?

The problem is that you are not calling a (standalone) function, but a class method. You can’t use class methods outside of their context, i.e. you can only use them on an instance of that class.

So, instead I should somehow connect the hook with MyClass instead of the function? How would I go about Kirby hooks, object-oriented?

Create an instance of your object inside the hook function and call the method on it. Example from one of my plugins:

kirby()->hook('panel.page.update', function ($page, $oldpage) {
  logger()->save('page.update', $page->uri(), $page->content()->toArray(), $oldpage->content()->toArray());
});

where logger() creates an instance of the Logger class and save() is the method called.

I’d put the hook outside of the class file, either into the main plugin file or into a separate hooks file, depending on how many hooks there are.

Will try that and get back to you, thanks so far!

<?php

function pdf() {
  require_once __DIR__ . DS . 'lib' . DS . 'lib.php';
  return new Kirby\Plugins\MyPlugin\MyClass;
}

kirby()->hook('panel.file.upload', function ($file) {
  pdf()->createPDF($file);
});

… works like a charm, thank you!