Browse Source

Enable plugin unload to modify Application.

By default modify the Application if it is defined. This makes `plugin
unload` mirror the behavior of `plugin load`.
Mark Story 8 years ago
parent
commit
efbe018de7
2 changed files with 89 additions and 4 deletions
  1. 38 0
      src/Shell/Task/UnloadTask.php
  2. 51 4
      tests/TestCase/Shell/Task/UnloadTaskTest.php

+ 38 - 0
src/Shell/Task/UnloadTask.php

@@ -52,12 +52,45 @@ class UnloadTask extends Shell
             return false;
         }
 
+        $app = APP . 'Application.php';
+        if (file_exists($app) && !$this->param('no_app')) {
+            $this->modifyApplication($app, $plugin);
+
+            return true;
+        }
+
         return (bool)$this->_modifyBootstrap($plugin);
     }
 
     /**
      * Update the applications bootstrap.php file.
      *
+     * @param string $app Path to the application to update.
+     * @param string $plugin Name of plugin.
+     * @return bool If modify passed.
+     */
+    protected function modifyApplication($app, $plugin)
+    {
+        $finder = "@\\\$this\-\>addPlugin\(\s*'$plugin'(.|.\n|)+\);+@";
+
+        $content = file_get_contents($app);
+        $newContent = preg_replace($finder, '', $content);
+
+        if ($newContent === $content) {
+            return false;
+        }
+
+        file_put_contents($app, $newContent);
+
+        $this->out('');
+        $this->out(sprintf('%s modified', $app));
+
+        return true;
+    }
+
+    /**
+     * Update the applications bootstrap.php file.
+     *
      * @param string $plugin Name of plugin.
      * @return bool If modify passed.
      */
@@ -100,6 +133,11 @@ class UnloadTask 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.',
             ]);

+ 51 - 4
tests/TestCase/Shell/Task/UnloadTaskTest.php

@@ -31,9 +31,19 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
     /**
      * @var string
      */
+    protected $app;
+
+    /**
+     * @var string
+     */
     protected $originalBootstrapContent;
 
     /**
+     * @var string
+     */
+    protected $originalAppContent;
+
+    /**
      * setUp method
      *
      * @return void
@@ -42,9 +52,10 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
     {
         parent::setUp();
         $this->bootstrap = ROOT . DS . 'config' . DS . 'bootstrap.php';
+        $this->app = APP . DS . 'Application.php';
 
-        $bootstrap = new File($this->bootstrap, false);
-        $this->originalBootstrapContent = $bootstrap->read();
+        $this->originalBootstrapContent = file_get_contents($this->bootstrap);
+        $this->originalAppContent = file_get_contents($this->app);
     }
 
     /**
@@ -59,6 +70,7 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
         Plugin::unload();
 
         file_put_contents($this->bootstrap, $this->originalBootstrapContent);
+        file_put_contents($this->app, $this->originalAppContent);
     }
 
     /**
@@ -75,7 +87,7 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
         $expected = "Plugin::load('TestPlugin', ['autoload' => true, 'bootstrap' => false, 'routes' => false]);";
         $this->assertContains($expected, $contents);
 
-        $this->exec('plugin unload TestPlugin');
+        $this->exec('plugin unload --no_app TestPlugin');
 
         $this->assertExitCode(Shell::CODE_SUCCESS);
         $contents = file_get_contents($this->bootstrap);
@@ -157,7 +169,7 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
         $bootstrap = new File($this->bootstrap, false);
         $bootstrap->append($content);
 
-        $this->exec('plugin unload TestPlugin');
+        $this->exec('plugin unload --no_app TestPlugin');
         $this->assertExitCode(Shell::CODE_SUCCESS);
 
         $result = $bootstrap->read();
@@ -165,6 +177,26 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
     }
 
     /**
+     * This method will tests multiple notations of plugin loading in the application class
+     *
+     * @dataProvider variantProvider
+     * @return void
+     */
+    public function testRegularExpressionsApplication($content)
+    {
+        $content = str_replace('Plugin::load', "        \$this->addPlugin", $content);
+        $this->addPluginToApp($content);
+
+        $this->exec('plugin unload TestPlugin');
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+
+        $result = file_get_contents($this->app);
+
+        $this->assertNotContains("addPlugin('TestPlugin'", $result);
+        $this->assertNotRegexp("/this\-\>addPlugin\([\'\"]TestPlugin'[\'\"][^\)]*\)\;/mi", $result);
+    }
+
+    /**
      * _addPluginToBootstrap
      *
      * Quick method to add a plugin to the bootstrap file.
@@ -177,4 +209,19 @@ class UnloadTaskTest extends ConsoleIntegrationTestCase
         $bootstrap = new File($this->bootstrap, false);
         $bootstrap->append("\n\nPlugin::load('$name', ['autoload' => true, 'bootstrap' => false, 'routes' => false]);\n");
     }
+
+    /**
+     * _addPluginToApp
+     *
+     * Quick method to add a plugin to the bootstrap file.
+     * This is useful for the tests
+     *
+     * @param string $insert The addPlugin line to add.
+     */
+    protected function addPluginToApp($insert)
+    {
+        $contents = file_get_contents($this->app);
+        $contents = preg_replace('/(function bootstrap\(\)(?:\s+)\{)/m', '$1' . $insert, $contents);
+        file_put_contents($this->app, $contents);
+    }
 }