Browse Source

Add plugins via application class methods.

If the application class is present, use its methods to load a plugin.
Mark Story 8 years ago
parent
commit
a09caafeeb
2 changed files with 98 additions and 27 deletions
  1. 56 16
      src/Shell/Task/LoadTask.php
  2. 42 11
      tests/TestCase/Shell/Task/LoadTaskTest.php

+ 56 - 16
src/Shell/Task/LoadTask.php

@@ -52,35 +52,70 @@ class LoadTask extends Shell
             return false;
         }
 
-        return $this->_modifyBootstrap(
-            $plugin,
-            $this->params['bootstrap'],
-            $this->params['routes'],
-            $this->params['autoload']
-        );
+        $options = $this->makeOptions();
+
+        $app = APP . 'Application.php';
+        if (file_exists($app) && !$this->param('no_app')) {
+            return $this->modifyApplication($app, $plugin, $options);
+        }
+
+        return $this->_modifyBootstrap($plugin, $options);
+    }
+
+    /**
+     * Create options string for the load call.
+     *
+     * @return string
+     */
+    protected function makeOptions()
+    {
+        $autoloadString = $this->param('autoload') ? "'autoload' => true" : '';
+        $bootstrapString = $this->param('bootstrap') ? "'bootstrap' => true" : '';
+        $routesString = $this->param('routes') ? "'routes' => true" : '';
+
+        return implode(', ', array_filter([$autoloadString, $bootstrapString, $routesString]));
+    }
+
+    /**
+     * Modify the application class
+     *
+     * @param string $app The Application file to modify.
+     * @param string $plugin The plugin name to add.
+     * @param string $options The plugin options to add
+     * @return void
+     */
+    protected function modifyApplication($app, $plugin, $options)
+    {
+        $file = new File($app, false);
+        $contents = $file->read();
+
+        $append = "\n        \$this->addPlugin('%s', [%s]);\n";
+        $insert = str_replace(', []', '', sprintf($append, $plugin, $options));
+
+        if (!preg_match('/function bootstrap\(\)/m', $contents)) {
+            $this->abort('Your Application class does not have a bootstrap() method. Please add one.');
+        } else {
+            $contents = preg_replace('/(function bootstrap\(\)(?:\s+)\{)/m', '$1' . $insert, $contents);
+        }
+        $file->write($contents);
+
+        $this->out('');
+        $this->out(sprintf('%s modified', $app));
     }
 
     /**
      * Update the applications bootstrap.php file.
      *
      * @param string $plugin Name of plugin.
-     * @param bool $hasBootstrap Whether or not bootstrap should be loaded.
-     * @param bool $hasRoutes Whether or not routes should be loaded.
-     * @param bool $hasAutoloader Whether or not there is an autoloader configured for
-     * the plugin.
+     * @param string $options The options string
      * @return bool If modify passed.
      */
-    protected function _modifyBootstrap($plugin, $hasBootstrap, $hasRoutes, $hasAutoloader)
+    protected function _modifyBootstrap($plugin, $options)
     {
         $bootstrap = new File($this->bootstrap, false);
         $contents = $bootstrap->read();
         if (!preg_match("@\n\s*Plugin::loadAll@", $contents)) {
-            $autoloadString = $hasAutoloader ? "'autoload' => true" : '';
-            $bootstrapString = $hasBootstrap ? "'bootstrap' => true" : '';
-            $routesString = $hasRoutes ? "'routes' => true" : '';
-
             $append = "\nPlugin::load('%s', [%s]);\n";
-            $options = implode(', ', array_filter([$autoloadString, $bootstrapString, $routesString]));
 
             $bootstrap->append(str_replace(', []', '', sprintf($append, $plugin, $options)));
             $this->out('');
@@ -124,6 +159,11 @@ class LoadTask extends Shell
                     'boolean' => true,
                     'default' => false,
                 ])
+                ->addOption('no_app', [
+                    'help' => 'Do not update the Application if it exist. Forces config/bootstrap.php to be updated.',
+                    'boolean' => true,
+                    'default' => false,
+                ])
                 ->addArgument('plugin', [
                     'help' => 'Name of the plugin to load.',
                 ]);

+ 42 - 11
tests/TestCase/Shell/Task/LoadTaskTest.php

@@ -37,15 +37,6 @@ class LoadTaskTest extends ConsoleIntegrationTestCase
     {
         parent::setUp();
 
-        $this->io = $this->getMockBuilder('Cake\Console\ConsoleIo')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->Task = $this->getMockBuilder('Cake\Shell\Task\LoadTask')
-            ->setMethods(['in', 'out', 'err', '_stop'])
-            ->setConstructorArgs([$this->io])
-            ->getMock();
-
         $this->app = APP . DS . 'Application.php';
         $this->bootstrap = ROOT . DS . 'config' . DS . 'bootstrap.php';
         $this->bootstrapCli = ROOT . DS . 'config' . DS . 'bootstrap_cli.php';
@@ -66,8 +57,6 @@ class LoadTaskTest extends ConsoleIntegrationTestCase
     public function tearDown()
     {
         parent::tearDown();
-        unset($this->shell);
-        Plugin::unload();
 
         $bootstrap = new File($this->bootstrap, false);
         $bootstrap->write($this->originalBootstrapContent);
@@ -172,4 +161,46 @@ class LoadTaskTest extends ConsoleIntegrationTestCase
         $contents = file_get_contents($this->bootstrap);
         $this->assertContains("Plugin::load('TestPlugin');", $contents);
     }
+
+    /**
+     * Test loading the app
+     *
+     * @return void
+     */
+    public function testLoadApp()
+    {
+        $this->exec('plugin load TestPlugin');
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+
+        $contents = file_get_contents($this->app);
+        $this->assertContains("\$this->addPlugin('TestPlugin');", $contents);
+    }
+
+    /**
+     * Test loading the app
+     *
+     * @return void
+     */
+    public function testLoadAppBootstrap()
+    {
+        $this->exec('plugin load --bootstrap TestPlugin');
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+
+        $contents = file_get_contents($this->app);
+        $this->assertContains("\$this->addPlugin('TestPlugin', ['bootstrap' => true]);", $contents);
+    }
+
+    /**
+     * Test loading the app
+     *
+     * @return void
+     */
+    public function testLoadAppRoutes()
+    {
+        $this->exec('plugin load --routes TestPlugin');
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+
+        $contents = file_get_contents($this->app);
+        $this->assertContains("\$this->addPlugin('TestPlugin', ['routes' => true]);", $contents);
+    }
 }