PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/CoreConsole/Commands/GeneratePlugin.php

https://github.com/CodeYellowBV/piwik
PHP | 223 lines | 148 code | 40 blank | 35 comment | 15 complexity | db0b081080511aa154705377130d778f MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik\Plugins\CoreConsole\Commands;
  10. use Piwik\Filesystem;
  11. use Symfony\Component\Console\Input\ArrayInput;
  12. use Symfony\Component\Console\Input\InputInterface;
  13. use Symfony\Component\Console\Input\InputOption;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. /**
  16. */
  17. class GeneratePlugin extends GeneratePluginBase
  18. {
  19. protected function configure()
  20. {
  21. $this->setName('generate:plugin')
  22. ->setAliases(array('generate:theme'))
  23. ->setDescription('Generates a new plugin/theme including all needed files')
  24. ->addOption('name', null, InputOption::VALUE_REQUIRED, 'Plugin name ([a-Z0-9_-])')
  25. ->addOption('description', null, InputOption::VALUE_REQUIRED, 'Plugin description, max 150 characters')
  26. ->addOption('pluginversion', null, InputOption::VALUE_OPTIONAL, 'Plugin version')
  27. ->addOption('full', null, InputOption::VALUE_OPTIONAL, 'If a value is set, an API and a Controller will be created as well. Option is only available for creating plugins, not for creating themes.');
  28. }
  29. protected function execute(InputInterface $input, OutputInterface $output)
  30. {
  31. $isTheme = $this->isTheme($input);
  32. $pluginName = $this->getPluginName($input, $output);
  33. $description = $this->getPluginDescription($input, $output);
  34. $version = $this->getPluginVersion($input, $output);
  35. $createFullPlugin = !$isTheme && $this->getCreateFullPlugin($input, $output);
  36. $this->generatePluginFolder($pluginName);
  37. if ($isTheme) {
  38. $exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExampleTheme';
  39. $replace = array(
  40. 'ExampleTheme' => $pluginName,
  41. 'ExampleDescription' => $description,
  42. '0.1.0' => $version
  43. );
  44. $whitelistFiles = array();
  45. } else {
  46. $exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
  47. $replace = array(
  48. 'ExamplePlugin' => $pluginName,
  49. 'ExampleDescription' => $description,
  50. '0.1.0' => $version
  51. );
  52. $whitelistFiles = array(
  53. '/ExamplePlugin.php',
  54. '/plugin.json',
  55. '/README.md',
  56. '/.travis.yml',
  57. '/screenshots',
  58. '/screenshots/.gitkeep',
  59. '/javascripts',
  60. '/javascripts/plugin.js',
  61. );
  62. }
  63. $this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
  64. $this->writeSuccessMessage($output, array(
  65. sprintf('%s %s %s generated.', $isTheme ? 'Theme' : 'Plugin', $pluginName, $version),
  66. 'Enjoy!'
  67. ));
  68. if ($createFullPlugin) {
  69. $this->executePluginCommand($output, 'generate:api', $pluginName);
  70. $this->executePluginCommand($output, 'generate:controller', $pluginName);
  71. }
  72. }
  73. private function executePluginCommand(OutputInterface $output, $commandName, $pluginName)
  74. {
  75. $command = $this->getApplication()->find($commandName);
  76. $arguments = array(
  77. 'command' => $commandName,
  78. '--pluginname' => $pluginName
  79. );
  80. $input = new ArrayInput($arguments);
  81. $command->run($input, $output);
  82. }
  83. /**
  84. * @param InputInterface $input
  85. * @return bool
  86. */
  87. private function isTheme(InputInterface $input)
  88. {
  89. $commandName = $input->getFirstArgument();
  90. return false !== strpos($commandName, 'theme');
  91. }
  92. protected function generatePluginFolder($pluginName)
  93. {
  94. $pluginPath = $this->getPluginPath($pluginName);
  95. Filesystem::mkdir($pluginPath);
  96. }
  97. /**
  98. * @param InputInterface $input
  99. * @param OutputInterface $output
  100. * @return array
  101. * @throws \RunTimeException
  102. */
  103. protected function getPluginName(InputInterface $input, OutputInterface $output)
  104. {
  105. $self = $this;
  106. $validate = function ($pluginName) use ($self) {
  107. if (empty($pluginName)) {
  108. throw new \RunTimeException('You have to enter a plugin name');
  109. }
  110. if (!Filesystem::isValidFilename($pluginName)) {
  111. throw new \RunTimeException(sprintf('The plugin name %s is not valid', $pluginName));
  112. }
  113. $pluginPath = $self->getPluginPath($pluginName);
  114. if (file_exists($pluginPath)) {
  115. throw new \RunTimeException('A plugin with this name already exists');
  116. }
  117. return $pluginName;
  118. };
  119. $pluginName = $input->getOption('name');
  120. if (empty($pluginName)) {
  121. $dialog = $this->getHelperSet()->get('dialog');
  122. $pluginName = $dialog->askAndValidate($output, 'Enter a plugin name: ', $validate);
  123. } else {
  124. $validate($pluginName);
  125. }
  126. $pluginName = ucfirst($pluginName);
  127. return $pluginName;
  128. }
  129. /**
  130. * @param InputInterface $input
  131. * @param OutputInterface $output
  132. * @return mixed
  133. * @throws \RunTimeException
  134. */
  135. protected function getPluginDescription(InputInterface $input, OutputInterface $output)
  136. {
  137. $validate = function ($description) {
  138. if (empty($description)) {
  139. throw new \RunTimeException('You have to enter a description');
  140. }
  141. if (150 < strlen($description)) {
  142. throw new \RunTimeException('Description is too long, max 150 characters allowed.');
  143. }
  144. return $description;
  145. };
  146. $description = $input->getOption('description');
  147. if (empty($description)) {
  148. $dialog = $this->getHelperSet()->get('dialog');
  149. $description = $dialog->askAndValidate($output, 'Enter a plugin description: ', $validate);
  150. } else {
  151. $validate($description);
  152. }
  153. return $description;
  154. }
  155. /**
  156. * @param InputInterface $input
  157. * @param OutputInterface $output
  158. * @return string
  159. */
  160. protected function getPluginVersion(InputInterface $input, OutputInterface $output)
  161. {
  162. $version = $input->getOption('pluginversion');
  163. if (is_null($version)) {
  164. $dialog = $this->getHelperSet()->get('dialog');
  165. $version = $dialog->ask($output, 'Enter a plugin version number (default to 0.1.0): ', '0.1.0');
  166. }
  167. return $version;
  168. }
  169. /**
  170. * @param InputInterface $input
  171. * @param OutputInterface $output
  172. * @return mixed
  173. */
  174. protected function getCreateFullPlugin(InputInterface $input, OutputInterface $output)
  175. {
  176. $full = $input->getOption('full');
  177. if (is_null($full)) {
  178. $dialog = $this->getHelperSet()->get('dialog');
  179. $full = $dialog->askConfirmation($output, 'Shall we also create an API and a Controller? (y/N)', false);
  180. }
  181. return !empty($full);
  182. }
  183. }