Check in plugin if other plugin exists

I am trying to build modular plugins as optional extensions to my plugin. IS there a way to check in one plugin that another exists?

For example load routes only if class exists? it’s problematic because I don’t know if plugins are loaded in a specific order?

Check out this post as regards load order: Plugin load order?

This makes snese, but two new questions come up one I’m gonna play with right now.

  1. What happens if I load a plugin that doesnt exist (answer to this in couple of minutes)

Answer: nothing happens - it returns false. very good.

  1. how do I prevent my plugin from stopping other plugins from loading? Since I’m using my own router inside the panel - it means that anything that happens after the router doesn’t function.

EDIT

Ok, not my “ideal” solution, but what I’m planning to do is copy parts of the kirby plugin loading to load the rest, while at the same time preventing loading the plugin again and again (infinite loops are bad)
Before I dive into this (Im not at home atm) - would I need to do the same to addons (panel fields for example) not defined in plugins directory?

That’s unfortunately not going to work. You can’t “wait” for other plugins to load before registering your router. I see two workarounds:

  • Define your router in a plugin like zzzz_myplugin to ensure that it always loads last, but: a) not very elegant and b) not compatible with the “load plugin from another plugin” approach
  • Make your modular extension modules register themselves at your main plugin; this approach will work if each module needs its own separate routes, you could then register a router for each module

Stopping execution inside plugins (e.g. with routers) is a very difficult topic. Something like a “all plugins are loaded” hook so that plugins can be notified and register their routers could work, but that would still not solve the issue for other Kirby extensions like fields, widgets etc.

Ok, I managed to do it. basically like I said I made a function that skips the current plugin (since the router works after all the plugin is loaded anyway. And just make sure that it skips the plugin that I’m already running (just so it won’t keep loading again and again)

function loadPlugins($skip = []){
   $kirby = kirby();
   if (! is_array($kirby->plugins)) {
      $kirby->plugins = [];
   }

   $root = $kirby->roots->plugins();

   // check for an existing plugins dir
   if(!is_dir($root)) return $kirby->plugins;

   foreach(array_diff(scandir($root), array('.', '..')) as $file) {
      if(!in_array($file,$skip)){
         if(is_dir($root . DS . $file)) {
            $kirby->plugin($file, 'dir');
         } else if(\f::extension($file) == 'php') {
            $kirby->plugin(f::name($file), 'file');
         }
      }
   }

}

The important thing here is to call this function after I already know my router is going to work, and before calling its function.

seems to work so far. But @lukasbestle - you’re the expert, do you see any reason it won’t? (I don’t wanna do a lot of work and then discover that it’s based on something buggy)

Well, it looks like a hack and I wouldn’t depend on it. I don’t know if it will work or not, just try it out. :slight_smile:

it is indeed a hack. but I really want to extend the panel :stuck_out_tongue:

it does work as far as I can see!

Can we ask for plugins loaded hook for kirby 2.4?

Not for Kirby 2.4 because of fields, widgets etc. It’s just more complex than it seems, but we will keep this in mind.

1 Like

Aight, Ill put this a solved for now - We need a hackily solved tag :wink:

1 Like