瀏覽代碼

Let Pico load plugins from vendor/pico-plugin.php

Split the Pico::loadPlugins() method to Pico::loadLocalPlugins() and Pico::loadComposerPlugins()
Daniel Rudolf 8 年之前
父節點
當前提交
23ad80b98a
共有 1 個文件被更改,包括 67 次插入12 次删除
  1. 67 12
      lib/Pico.php

+ 67 - 12
lib/Pico.php

@@ -441,6 +441,29 @@ class Pico
         return $output;
     }
 
+    /**
+     * Loads plugins from vendor/pico-plugin.php and Pico::$pluginsDir
+     *
+     * See {@see Pico::loadLocalPlugins()} for details about plugins installed
+     * to {@see Pico::$pluginsDir}, and {@see Pico::loadComposerPlugins()} for
+     * details about plugins installed using `composer`.
+     *
+     * Please note that Pico will change the processing order when needed to
+     * incorporate plugin dependencies. See {@see Pico::sortPlugins()} for
+     * details.
+     *
+     * @see    Pico::loadPlugin()
+     * @see    Pico::getPlugin()
+     * @see    Pico::getPlugins()
+     * @return void
+     * @throws RuntimeException thrown when a plugin couldn't be loaded
+     */
+    protected function loadPlugins()
+    {
+        $this->loadLocalPlugins();
+        $this->loadComposerPlugins();
+    }
+
     /**
      * Loads plugins from Pico::$pluginsDir in alphabetical order
      *
@@ -459,19 +482,13 @@ class Pico
      * - 60 to 79: Plugins hooking into template or markdown parsing
      * - 80 to 99: Plugins using the `onPageRendered` event
      *
-     * Please note that Pico will change the processing order when needed to
-     * incorporate plugin dependencies. See {@see Pico::sortPlugins()} for
-     * details.
-     *
-     * @see    Pico::loadPlugin()
-     * @see    Pico::getPlugin()
-     * @see    Pico::getPlugins()
+     * @see    Pico::loadPlugins()
+     * @see    Pico::loadComposerPlugins()
      * @return void
      * @throws RuntimeException thrown when a plugin couldn't be loaded
      */
-    protected function loadPlugins()
+    protected function loadLocalPlugins()
     {
-        // discover plugin files
         $pluginFiles = array();
         $files = scandir($this->getPluginsDir());
         if ($files !== false) {
@@ -504,9 +521,9 @@ class Pico
             }
         }
 
-        // scope isolated require_once()
+        // scope isolated require()
         $includeClosure = function ($pluginFile) {
-            require_once($pluginFile);
+            require($pluginFile);
         };
         if (PHP_VERSION_ID >= 50400) {
             $includeClosure = $includeClosure->bindTo(null);
@@ -537,6 +554,44 @@ class Pico
         }
     }
 
+    /**
+     * Loads plugins from vendor/pico-plugin.php
+     *
+     * This method loads all plugins installed using `composer` and Pico's
+     * `picocms/pico-composer` installer by reading the `pico-plugin.php` in
+     * composer's `vendor` dir. Using composer enables plugin developers to
+     * load multiple plugins and their dependencies using a single composer
+     * package.
+     *
+     * @see    Pico::loadPlugins()
+     * @see    Pico::loadLocalPlugins()
+     * @return void
+     */
+    protected function loadComposerPlugins()
+    {
+        $composerPlugins = array();
+        if (file_exists($this->vendorDir . 'vendor/pico-plugin.php')) {
+            // composer root package
+            $composerPlugins = require($this->vendorDir . 'vendor/pico-plugin.php') ?: array();
+        } elseif (file_exists($this->vendorDir . '../../../vendor/pico-plugin.php')) {
+            // composer dependency package
+            $composerPlugins = require($this->vendorDir . '../../../vendor/pico-plugin.php') ?: array();
+        }
+
+        foreach ($composerPlugins as $package => $classNames) {
+            foreach ($classNames as $className) {
+                $plugin = new $className($this);
+                $this->plugins[$className] = $plugin;
+
+                if ($plugin instanceof PicoPluginInterface) {
+                    if (defined($className . '::API_VERSION') && ($className::API_VERSION >= static::API_VERSION)) {
+                        $this->nativePlugins[$className] = $plugin;
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Manually loads a plugin
      *
@@ -2043,7 +2098,7 @@ class Pico
      * Please note that {@see PicoDeprecated} also triggers custom events on
      * plugins using older API versions, thus you can safely use this method
      * to trigger custom events on all loaded plugins, no matter what API
-     * version - the event will be triggered in any case
+     * version - the event will be triggered in any case.
      *
      * You MUST NOT trigger events of Pico's core with a plugin!
      *