Browse Source

Allow adding plugins using a config array.

Refs #16537.
ADmad 3 years ago
parent
commit
e71a04c057

+ 44 - 0
src/Core/PluginCollection.php

@@ -16,6 +16,7 @@ declare(strict_types=1);
 namespace Cake\Core;
 
 use Cake\Core\Exception\MissingPluginException;
+use Cake\Utility\Hash;
 use Countable;
 use Generator;
 use InvalidArgumentException;
@@ -79,6 +80,49 @@ class PluginCollection implements Iterator, Countable
     }
 
     /**
+     * Add plugins from config array.
+     *
+     * @param array $config Configuration array. For e.g.:
+     *   ```
+     *   [
+     *       'Company/TestPluginThree',
+     *       'TestPlugin' => ['onlyDebug' => true, 'onlyCli' => true],
+     *       'Nope' => ['optional' => true],
+     *       'Named' => ['routes' => false, 'bootstrap' => false],
+     *   ]
+     *   ```
+     * @return void
+     */
+    public function addFromConfig(array $config): void
+    {
+        $debug = Configure::read('debug');
+        $cli = PHP_SAPI === 'cli';
+
+        foreach (Hash::normalize($config) as $name => $options) {
+            $options = (array)$options;
+            $onlyDebug = $options['onlyDebug'] ?? false;
+            $onlyCli = $options['onlyCli'] ?? false;
+            $optional = $options['optional'] ?? false;
+
+            if (
+                ($onlyDebug && !$debug)
+                || ($onlyCli && !$cli)
+            ) {
+                continue;
+            }
+
+            try {
+                $plugin = $this->create($name, $options);
+                $this->add($plugin);
+            } catch (MissingPluginException $e) {
+                if (!$optional) {
+                    throw $e;
+                }
+            }
+        }
+    }
+
+    /**
      * Load the path information stored in vendor/cakephp-plugins.php
      *
      * This file is generated by the cakephp/plugin-installer package and used

+ 6 - 0
src/Http/BaseApplication.php

@@ -174,6 +174,12 @@ abstract class BaseApplication implements
     public function bootstrap(): void
     {
         require_once $this->configDir . 'bootstrap.php';
+
+        // phpcs:ignore
+        $plugins = @include_once $this->configDir . 'plugins.php';
+        if (is_array($plugins)) {
+            $this->plugins->addFromConfig($plugins);
+        }
     }
 
     /**

+ 20 - 0
tests/TestCase/Core/PluginCollectionTest.php

@@ -48,6 +48,26 @@ class PluginCollectionTest extends TestCase
         $this->assertCount(1, $plugins);
     }
 
+    public function testAddFromConfig()
+    {
+        Configure::write('debug', false);
+
+        $config = [
+            'Company/TestPluginThree',
+            'TestPlugin' => ['onlyDebug' => true],
+            'Nope' => ['optional' => true],
+            'Named' => ['routes' => false],
+        ];
+
+        $plugins = new PluginCollection();
+        $plugins->addFromConfig($config);
+
+        $this->assertCount(2, $plugins);
+        $this->assertTrue($plugins->has('Company/TestPluginThree'));
+        $this->assertFalse($plugins->has('TestPlugin'));
+        $this->assertFalse($plugins->get('Named')->isEnabled('routes'));
+    }
+
     public function testAddOperations(): void
     {
         $plugins = new PluginCollection();

+ 2 - 0
tests/test_app/config/plugins.php

@@ -0,0 +1,2 @@
+<?php
+return [];