diff --git a/src/Shell/Task/LoadTask.php b/src/Shell/Task/LoadTask.php index 8fff05c4810..b77b466a44e 100644 --- a/src/Shell/Task/LoadTask.php +++ b/src/Shell/Task/LoadTask.php @@ -52,35 +52,70 @@ public function main($plugin = null) 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 @@ public function getOptionParser() '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.', ]); diff --git a/tests/TestCase/Shell/Task/LoadTaskTest.php b/tests/TestCase/Shell/Task/LoadTaskTest.php index 0dcef79a17a..2d2ab5f3457 100644 --- a/tests/TestCase/Shell/Task/LoadTaskTest.php +++ b/tests/TestCase/Shell/Task/LoadTaskTest.php @@ -37,15 +37,6 @@ public function setUp() { 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 @@ public function setUp() public function tearDown() { parent::tearDown(); - unset($this->shell); - Plugin::unload(); $bootstrap = new File($this->bootstrap, false); $bootstrap->write($this->originalBootstrapContent); @@ -172,4 +161,46 @@ public function testLoadNothing() $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); + } }