PageRenderTime 81ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/Installer/src/Shell/PluginsShell.php

http://github.com/QuickAppsCMS/QuickApps-CMS
PHP | 356 lines | 253 code | 34 blank | 69 comment | 31 complexity | 6bc7e6a9fd162a024f099caf93d8c07c MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, GPL-3.0
  1. <?php
  2. /**
  3. * Licensed under The GPL-3.0 License
  4. * For full copyright and license information, please see the LICENSE.txt
  5. * Redistributions of files must retain the above copyright notice.
  6. *
  7. * @since 2.0.0
  8. * @author Christopher Castro <chris@quickapps.es>
  9. * @link http://www.quickappscms.org
  10. * @license http://opensource.org/licenses/gpl-3.0.html GPL-3.0 License
  11. */
  12. namespace Installer\Shell;
  13. use Cake\Console\Shell;
  14. use CMS\Core\Plugin;
  15. /**
  16. * Shell for plugins management.
  17. *
  18. */
  19. class PluginsShell extends Shell
  20. {
  21. /**
  22. * Contains tasks to load and instantiate.
  23. *
  24. * @var array
  25. */
  26. public $tasks = [
  27. 'Installer.PluginInstall',
  28. 'Installer.PluginUninstall',
  29. 'Installer.PluginToggle',
  30. ];
  31. /**
  32. * Removes the welcome message.
  33. *
  34. * @return void
  35. */
  36. public function startup()
  37. {
  38. }
  39. /**
  40. * Gets the option parser instance and configures it.
  41. *
  42. * @return \Cake\Console\ConsoleOptionParser
  43. */
  44. public function getOptionParser()
  45. {
  46. $parser = parent::getOptionParser();
  47. $parser
  48. ->description(__d('installer', 'Plugins maintenance commands.'))
  49. ->addSubcommand('install', [
  50. 'help' => __d('installer', 'Install a new plugin.'),
  51. 'parser' => $this->PluginInstall->getOptionParser(),
  52. ])
  53. ->addSubcommand('uninstall', [
  54. 'help' => __d('installer', 'Uninstalls an existing plugin.'),
  55. 'parser' => $this->PluginUninstall->getOptionParser(),
  56. ])
  57. ->addSubcommand('toggle', [
  58. 'help' => __d('installer', 'Enable or disable a plugin.'),
  59. 'parser' => $this->PluginToggle->getOptionParser(),
  60. ]);
  61. return $parser;
  62. }
  63. /**
  64. * Override main() for help message hook
  65. *
  66. * @return void
  67. */
  68. public function main()
  69. {
  70. $this->out(__d('installer', '<info>Plugins Shell</info>'));
  71. $this->hr();
  72. $this->out(__d('installer', '[1] Install new plugin'));
  73. $this->out(__d('installer', '[2] Remove an existing plugin'));
  74. $this->out(__d('installer', '[3] Enable plugin'));
  75. $this->out(__d('installer', '[4] Disable plugin'));
  76. $this->out(__d('installer', '[H]elp'));
  77. $this->out(__d('installer', '[Q]uit'));
  78. $choice = (string)strtolower($this->in(__d('installer', 'What would you like to do?'), ['1', '2', '3', '4', 'H', 'Q']));
  79. switch ($choice) {
  80. case '1':
  81. $this->_install();
  82. break;
  83. case '2':
  84. $this->_uninstall();
  85. break;
  86. case '3':
  87. $this->_enable();
  88. break;
  89. case '4':
  90. $this->_disable();
  91. break;
  92. case 'h':
  93. $this->out($this->OptionParser->help());
  94. break;
  95. case 'q':
  96. return $this->_stop();
  97. default:
  98. $this->out(__d('installer', 'You have made an invalid selection. Please choose a command to execute by entering 1, 2, 3, 4, H, or Q.'));
  99. }
  100. $this->hr();
  101. $this->main();
  102. }
  103. /**
  104. * Toogle task.
  105. *
  106. * @return bool
  107. */
  108. public function toggle()
  109. {
  110. return $this->PluginToggle->main();
  111. }
  112. /**
  113. * Install task.
  114. *
  115. * @return bool
  116. */
  117. public function install()
  118. {
  119. return $this->PluginInstall->main();
  120. }
  121. /**
  122. * Uninstall task.
  123. *
  124. * @return bool
  125. */
  126. public function uninstall()
  127. {
  128. return $this->PluginUninstall->main();
  129. }
  130. /**
  131. * Install a new plugin from URL, directory or ZIP.
  132. *
  133. * @return void
  134. */
  135. protected function _install()
  136. {
  137. $message = __d('installer', "Please provide a plugin source, it can be either an URL or a filesystem path to a ZIP/directory within your server?\n[Q]uit");
  138. while (true) {
  139. $source = $this->in($message);
  140. if (strtoupper($source) === 'Q') {
  141. $this->err(__d('installer', 'Installation aborted'));
  142. break;
  143. } else {
  144. $this->out(__d('installer', 'Starting installation...'), 0);
  145. $task = $this->dispatchShell("Installer.plugins install -s {$source}");
  146. if ($task === 0) {
  147. $this->_io->overwrite(__d('installer', 'Starting installation... successfully installed!'), 2);
  148. $this->out();
  149. break;
  150. } else {
  151. $this->_io->overwrite(__d('installer', 'Starting installation... failed!'), 2);
  152. $this->out();
  153. }
  154. }
  155. }
  156. $this->out();
  157. }
  158. /**
  159. * Uninstall a plugin.
  160. *
  161. * @return void
  162. */
  163. protected function _uninstall()
  164. {
  165. $allPlugins = plugin()
  166. ->filter(function ($plugin) {
  167. return !$plugin->isTheme;
  168. })
  169. ->toArray();
  170. $index = 1;
  171. $this->out();
  172. foreach ($allPlugins as $plugin) {
  173. $allPlugins[$index] = $plugin;
  174. $this->out(__d('installer', '[{0, number}] {1}', [$index, $plugin->humanName]));
  175. $index++;
  176. }
  177. $this->out();
  178. $message = __d('installer', "Which plugin would you like to uninstall?\n[Q]uit");
  179. while (true) {
  180. $in = $this->in($message);
  181. if (strtoupper($in) === 'Q') {
  182. $this->err(__d('installer', 'Operation aborted'));
  183. break;
  184. } elseif (intval($in) < 1 || !isset($allPlugins[intval($in)])) {
  185. $this->err(__d('installer', 'Invalid option'));
  186. } else {
  187. $plugin = plugin($allPlugins[$in]->name());
  188. $this->hr();
  189. $this->out(__d('installer', '<info>The following plugin will be UNINSTALLED</info>'));
  190. $this->hr();
  191. $this->out(__d('installer', 'Name: {0}', $plugin->name));
  192. $this->out(__d('installer', 'Description: {0}', $plugin->composer['description']));
  193. $this->out(__d('installer', 'Status: {0}', ($plugin->status ? __d('installer', 'Active') : __d('installer', 'Disabled'))));
  194. $this->out(__d('installer', 'Path: {0}', $plugin->path));
  195. $this->hr();
  196. $this->out();
  197. $confirm = $this->in(__d('installer', 'Please type in "{0}" to uninstall', $allPlugins[$in]->name));
  198. if ($confirm === $allPlugins[$in]->name) {
  199. $task = $this->dispatchShell("Installer.plugins uninstall -p {$allPlugins[$in]->name}");
  200. if ($task === 0) {
  201. $this->out(__d('installer', 'Plugin uninstalled!'));
  202. Plugin::dropCache();
  203. } else {
  204. $this->err(__d('installer', 'Plugin could not be uninstalled.'), 2);
  205. $this->out();
  206. }
  207. } else {
  208. $this->err(__d('installer', 'Confirmation failure, operation aborted!'));
  209. }
  210. break;
  211. }
  212. }
  213. $this->out();
  214. }
  215. /**
  216. * Activates a plugin.
  217. *
  218. * @return void
  219. */
  220. protected function _enable()
  221. {
  222. $disabledPlugins = plugin()
  223. ->filter(function ($plugin) {
  224. return !$plugin->status && !$plugin->isTheme;
  225. })
  226. ->toArray();
  227. if (!count($disabledPlugins)) {
  228. $this->err(__d('installer', '<info>There are no disabled plugins!</info>'));
  229. $this->out();
  230. return;
  231. }
  232. $index = 1;
  233. $this->out();
  234. foreach ($disabledPlugins as $plugin) {
  235. $disabledPlugins[$index] = $plugin;
  236. $this->out(__d('installer', '[{0, number, integer}] {1}', [$index, $plugin->humanName]));
  237. $index++;
  238. }
  239. $this->out();
  240. $message = __d('installer', "Which plugin would you like to activate?\n[Q]uit");
  241. while (true) {
  242. $in = $this->in($message);
  243. if (strtoupper($in) === 'Q') {
  244. $this->err(__d('installer', 'Operation aborted'));
  245. break;
  246. } elseif (intval($in) < 1 || !isset($disabledPlugins[intval($in)])) {
  247. $this->err(__d('installer', 'Invalid option'));
  248. } else {
  249. $task = $this->dispatchShell("Installer.plugins toggle -p {$disabledPlugins[$in]->name} -s enable");
  250. if ($task === 0) {
  251. $this->out(__d('installer', 'Plugin enabled!'));
  252. Plugin::dropCache();
  253. } else {
  254. $this->err(__d('installer', 'Plugin could not be enabled.'), 2);
  255. $this->out();
  256. }
  257. break;
  258. }
  259. }
  260. $this->out();
  261. }
  262. /**
  263. * Disables a plugin.
  264. *
  265. * @return void
  266. */
  267. protected function _disable()
  268. {
  269. $enabledPlugins = plugin()
  270. ->filter(function ($plugin) {
  271. return $plugin->status && !$plugin->isTheme;
  272. })
  273. ->toArray();
  274. if (!count($enabledPlugins)) {
  275. $this->err(__d('installer', '<info>There are no active plugins!</info>'));
  276. $this->out();
  277. return;
  278. }
  279. $index = 1;
  280. $this->out();
  281. foreach ($enabledPlugins as $plugin) {
  282. $enabledPlugins[$index] = $plugin;
  283. $this->out(__d('installer', '[{0, number, integer}] {1}', [$index, $plugin->humanName]));
  284. $index++;
  285. }
  286. $this->out();
  287. $message = __d('installer', "Which plugin would you like to disable?\n[Q]uit");
  288. while (true) {
  289. $in = $this->in($message);
  290. if (strtoupper($in) === 'Q') {
  291. $this->err(__d('installer', 'Operation aborted'));
  292. break;
  293. } elseif (intval($in) < 1 || !isset($enabledPlugins[intval($in)])) {
  294. $this->err(__d('installer', 'Invalid option'));
  295. } else {
  296. $plugin = plugin($enabledPlugins[$in]->name());
  297. $this->hr();
  298. $this->out(__d('installer', '<info>The following plugin will be DISABLED</info>'));
  299. $this->hr();
  300. $this->out(__d('installer', 'Name: {0}', $plugin->name));
  301. $this->out(__d('installer', 'Description: {0}', $plugin->composer['description']));
  302. $this->out(__d('installer', 'Status: {0}', $plugin->status ? __d('installer', 'Active') : __d('installer', 'Disabled')));
  303. $this->out(__d('installer', 'Path: {0}', $plugin->path));
  304. $this->hr();
  305. $this->out();
  306. $confirm = $this->in(__d('installer', 'Please type in "{0}" to disable this plugin', $enabledPlugins[$in]->name));
  307. if ($confirm === $enabledPlugins[$in]->name) {
  308. $task = $this->dispatchShell("Installer.plugins toggle -p {$enabledPlugins[$in]->name} -s disable");
  309. if ($task === 0) {
  310. $this->out(__d('installer', 'Plugin disabled!'));
  311. Plugin::dropCache();
  312. } else {
  313. $this->err(__d('installer', 'Plugin could not be disabled.'), 2);
  314. $this->out();
  315. }
  316. }
  317. break;
  318. }
  319. }
  320. $this->out();
  321. }
  322. }