Skip to content

Commit

Permalink
Add plugins via application class methods.
Browse files Browse the repository at this point in the history
If the application class is present, use its methods to load a plugin.
  • Loading branch information
markstory committed Mar 2, 2018
1 parent 1b53551 commit a09caaf
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 27 deletions.
72 changes: 56 additions & 16 deletions src/Shell/Task/LoadTask.php
Expand Up @@ -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('');
Expand Down Expand Up @@ -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.',
]);
Expand Down
53 changes: 42 additions & 11 deletions tests/TestCase/Shell/Task/LoadTaskTest.php
Expand Up @@ -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';
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
}

0 comments on commit a09caaf

Please sign in to comment.