<?php
namespace Croogo\Core\Shell;
use App\Controller\AppController;
use Cake\Controller\Controller;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Http\Response;
use Cake\Http\ServerRequest;
use Cake\Utility\Inflector;
use Croogo\Core\PluginManager as CroogoPlugin;
use Croogo\Extensions\CroogoTheme;
/**
* Ext Shell
*
* Activate/Deactivate Plugins/Themes
* ./Console/croogo ext activate plugin Example
* ./Console/croogo ext activate theme minimal
* ./Console/croogo ext deactivate plugin Example
* ./Console/croogo ext deactivate theme
*
* @category Shell
* @package Croogo.Croogo.Console.Command
* @version 1.0
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link http://www.croogo.org
*/
class ExtShell extends AppShell
{
/**
* Models we use
*
* @var array
*/
public $uses = ['Settings.Setting'];
/**
* CroogoPlugin class
*
* @var CroogoPlugin
*/
protected $_CroogoPlugin = null;
/**
* CroogoTheme class
*
* @var CroogoTheme
*/
protected $_CroogoTheme = null;
/**
* Controller
*
* @var Controller
* @todo Remove this when PluginActivation dont need controllers
*/
protected $_Controller = null;
/**
* Initialize
*
* @param type $stdout
* @param type $stderr
* @param type $stdin
*/
public function __construct($stdout = null, $stderr = null, $stdin = null)
{
parent::__construct($stdout, $stderr, $stdin);
$this->_CroogoPlugin = new CroogoPlugin();
$this->_CroogoTheme = new CroogoTheme();
$Request = new ServerRequest();
$Response = new Response();
$this->_Controller = new AppController($Request, $Response);
$this->_Controller->startupProcess();
$this->_CroogoPlugin->setController($this->_Controller);
$this->initialize();
}
/**
* Call the appropriate command
*
* @return bool
*/
public function main()
{
$args = $this->args;
$this->args = array_map('strtolower', $this->args);
$method = $this->args[0];
$type = $this->args[1];
$ext = isset($args[2]) ? $args[2] : null;
$force = isset($this->params['force']) ? $this->params['force'] : false;
if ($type == 'theme') {
$extensions = $this->_CroogoTheme->getThemes();
$theme = Configure::read('Site.theme');
$active = !empty($theme) ? $theme == 'default' : true;
} elseif ($type == 'plugin') {
$extensions = $this->_CroogoPlugin->getPlugins();
if ($force) {
$plugins = array_combine($p = Plugin::loaded(), $p);
$extensions += $plugins;
}
$active = Plugin::isLoaded($ext);
}
if ($type == 'theme' && $method == 'deactivate') {
$this->err(__d('croogo', 'Theme cannot be deactivated, instead activate another theme.'));
return false;
}
if (!empty($ext) && !isset($extensions[$ext]) && !$active && !$force) {
$this->err(__d('croogo', '%s "%s" not found.', ucfirst($type), $ext));
return false;
}
switch ($method) {
case 'list':
$call = Inflector::pluralize($type);
return $this->{$call}($ext);
default:
if (empty($ext)) {
$this->err(__d('croogo', '%s name must be provided.', ucfirst($type)));
return false;
}
return $this->{'_' . $method . ucfirst($type)}($ext);
}
return true;
}
/**
* Display help/options
*/
public function getOptionParser()
{
return parent::getOptionParser()
->setDescription(__d('croogo', 'Activate Plugins & Themes'))
->addArguments([
'method' => [
'help' => __d('croogo', 'Method to perform'),
'required' => true,
'choices' => ['list', 'activate', 'deactivate'],
],
'type' => [
'help' => __d('croogo', 'Extension type'),
'required' => true,
'choices' => ['plugin', 'theme'],
],
'extension' => [
'help' => __d('croogo', 'Name of extension'),
],
])
->addOption('all', [
'short' => 'a',
'boolean' => true,
'help' => 'List all extensions',
])
->addOption('force', [
'short' => 'f',
'boolean' => true,
'help' => 'Force method operation even when plugin does not provide a `plugin.json` file.'
]);
}
/**
* Activate a plugin
*
* @param string $plugin
* @return bool
*/
protected function _activatePlugin($plugin)
{
$result = $this->_CroogoPlugin->activate($plugin);
if ($result === true) {
$this->out(__d('croogo', 'Plugin "%s" activated successfully.', $plugin));
return true;
} elseif (is_string($result)) {
$this->err($result);
} else {
$this->err(__d('croogo', 'Plugin "%s" could not be activated. Please, try again.', $plugin));
}
return false;
}
/**
* Deactivate a plugin
*
* @param string $plugin
* @return bool
*/
protected function _deactivatePlugin($plugin)
{
$usedBy = $this->_CroogoPlugin->usedBy($plugin);
if ($usedBy === false) {
$result = $this->_CroogoPlugin->deactivate($plugin);
if ($result === false) {
$this->err(__d('croogo', 'Plugin "%s" could not be deactivated. Please, try again.', $plugin));
} elseif (is_string($result)) {
$this->err($result);
}
} else {
$result = false;
if ($usedBy !== false) {
if ($this->params['force'] === false) {
$this->err(__d('croogo', 'Plugin "%s" could not be deactivated since "%s" depends on it.', $plugin, implode(', ', $usedBy)));
} else {
$result = true;
}
}
}
if ($this->params['force'] === true || $result === true) {
$this->_CroogoPlugin->removeBootstrap($plugin);
$result = true;
}
if ($result === true) {
$this->out(__d('croogo', 'Plugin "%s" deactivated successfully.', $plugin));
return true;
}
return false;
}
/**
* Activate a theme
*
* @param string $theme Name of theme
* @return bool
*/
protected function _activateTheme($theme)
{
if ($this->_CroogoTheme->activate($theme)) {
$this->out(__d('croogo', 'Theme "%s" activated successfully.', $theme));
} else {
$this->err(__d('croogo', 'Theme "%s" activation failed.', $theme));
}
return true;
}
/**
* List plugins
*/
public function plugins($plugin = null)
{
$all = $this->params['all'];
$plugins = $plugin == null ? array_keys(Configure::read('plugins')) : [$plugin];
$loaded = Plugin::loaded();
$CroogoPlugin = new CroogoPlugin();
$this->out(__d('croogo', 'Plugins:'), 2);
$this->out(__d('croogo', '%-20s%-50s%s', __d('croogo', 'Plugin'), __d('croogo', 'Author'), __d('croogo', 'Status')));
$this->out(str_repeat('-', 80));
foreach ($plugins as $plugin) {
$status = '<info>inactive</info>';
if ($active = in_array($plugin, $loaded)) {
$status = '<success>active</success>';
}
if (!$active && !$all) {
continue;
}
$data = $CroogoPlugin->getData($plugin);
$author = isset($data['author']) ? $data['author'] : '';
$this->out(__d('croogo', '%-20s%-50s%s', $plugin, $author, $status));
}
}
/**
* List themes
*/
public function themes($theme = null)
{
$CroogoTheme = new CroogoTheme();
$all = $this->params['all'];
$current = Configure::read('Site.theme');
$themes = $theme == null ? $CroogoTheme->getThemes() : [$theme];
$this->out("Themes:", 2);
$default = empty($current) || $current == 'default';
$this->out(__d('croogo', '%-20s%-50s%s', __d('croogo', 'Theme'), __d('croogo', 'Author'), __d('croogo', 'Status')));
$this->out(str_repeat('-', 80));
foreach ($themes as $theme) {
$active = $theme == $current || $default && $theme == 'default';
$status = $active ? '<success>active</success>' : '<info>inactive</info>';
if (!$active && !$all) {
continue;
}
$data = $CroogoTheme->getData($theme);
$author = isset($data['author']) ? $data['author'] : '';
$this->out(__d('croogo', '%-20s%-50s%s', $theme, $author, $status));
}
}
}