PluginCreateCommand.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. namespace Webman\Console\Commands;
  3. use Symfony\Component\Console\Command\Command;
  4. use Symfony\Component\Console\Input\InputInterface;
  5. use Symfony\Component\Console\Output\OutputInterface;
  6. use Symfony\Component\Console\Input\InputOption;
  7. use Webman\Console\Util;
  8. class PluginCreateCommand extends Command
  9. {
  10. protected static $defaultName = 'plugin:create';
  11. protected static $defaultDescription = 'Plugin create';
  12. /**
  13. * @return void
  14. */
  15. protected function configure()
  16. {
  17. $this->addOption('name', 'name', InputOption::VALUE_REQUIRED, 'Plugin name, for example foo/my-admin');
  18. }
  19. /**
  20. * @param InputInterface $input
  21. * @param OutputInterface $output
  22. * @return int
  23. */
  24. protected function execute(InputInterface $input, OutputInterface $output): int
  25. {
  26. $name = strtolower($input->getOption('name'));
  27. $output->writeln("Create Plugin $name");
  28. if (!strpos($name, '/')) {
  29. $output->writeln('<error>Bad name, name must contain character \'/\' , for example foo/MyAdmin</error>');
  30. return self::FAILURE;
  31. }
  32. $namespace = Util::nameToNamespace($name);
  33. // Create dir config/plugin/$name
  34. if (is_dir($plugin_config_path = config_path()."/plugin/$name")) {
  35. $output->writeln("<error>Dir $plugin_config_path already exists</error>");
  36. return self::FAILURE;
  37. }
  38. if (is_dir($plugin_path = base_path()."/vendor/$name")) {
  39. $output->writeln("<error>Dir $plugin_path already exists</error>");
  40. return self::FAILURE;
  41. }
  42. // Add psr-4
  43. if ($err = $this->addAutoloadToComposerJson($name, $namespace)) {
  44. $output->writeln("<error>$err</error>");
  45. return self::FAILURE;
  46. }
  47. $this->createConfigFiles($plugin_config_path);
  48. $this->createVendorFiles($name, $namespace, $plugin_path, $output);
  49. return self::SUCCESS;
  50. }
  51. protected function addAutoloadToComposerJson($name, $namespace)
  52. {
  53. if (!is_file($composer_json_file = base_path()."/composer.json")) {
  54. return "$composer_json_file not exists";
  55. }
  56. $composer_json = json_decode($composer_json_str = file_get_contents($composer_json_file), true);
  57. if (!$composer_json) {
  58. return "Bad $composer_json_file";
  59. }
  60. if(isset($composer_json['autoload']['psr-4'][$namespace."\\"])) {
  61. return;
  62. }
  63. $namespace = str_replace("\\", "\\\\", $namespace);
  64. $composer_json_str = str_replace('"psr-4": {', '"psr-4": {'."\n \"$namespace\\\\\" : \"vendor/$name/src\",", $composer_json_str);
  65. file_put_contents($composer_json_file, $composer_json_str);
  66. }
  67. protected function createConfigFiles($plugin_config_path)
  68. {
  69. mkdir($plugin_config_path, 0777, true);
  70. $app_str = <<<EOF
  71. <?php
  72. return [
  73. 'enable' => true,
  74. ];
  75. EOF;
  76. file_put_contents("$plugin_config_path/app.php", $app_str);
  77. }
  78. protected function createVendorFiles($name, $namespace, $plugin_path, $output)
  79. {
  80. mkdir("$plugin_path/src", 0777, true);
  81. $this->createComposerJson($name, $namespace, $plugin_path);
  82. if (is_callable('exec')) {
  83. exec("composer dumpautoload");
  84. } else {
  85. $output->writeln("<info>Please run command 'composer dumpautoload'</info>");
  86. }
  87. }
  88. /**
  89. * @param $name
  90. * @param $namespace
  91. * @param $dest
  92. * @return void
  93. */
  94. protected function createComposerJson($name, $namespace, $dest)
  95. {
  96. $namespace = str_replace('\\', '\\\\', $namespace);
  97. $composer_json_content = <<<EOT
  98. {
  99. "name": "$name",
  100. "type": "library",
  101. "license": "MIT",
  102. "description": "Webman plugin $name",
  103. "require": {
  104. },
  105. "autoload": {
  106. "psr-4": {
  107. "$namespace\\\\": "src"
  108. }
  109. }
  110. }
  111. EOT;
  112. file_put_contents("$dest/composer.json", $composer_json_content);
  113. }
  114. /**
  115. * @param $namespace
  116. * @param $path_relations
  117. * @param $dest_dir
  118. * @return void
  119. */
  120. protected function writeInstallFile($namespace, $path_relations, $dest_dir)
  121. {
  122. if (!is_dir($dest_dir)) {
  123. mkdir($dest_dir, 0777, true);
  124. }
  125. $relations = [];
  126. foreach($path_relations as $relation) {
  127. $relations[$relation] = $relation;
  128. }
  129. $relations = var_export($relations, true);
  130. $install_php_content = <<<EOT
  131. <?php
  132. namespace $namespace;
  133. class Install
  134. {
  135. const WEBMAN_PLUGIN = true;
  136. /**
  137. * @var array
  138. */
  139. protected static \$pathRelation = $relations;
  140. /**
  141. * Install
  142. * @return void
  143. */
  144. public static function install()
  145. {
  146. static::installByRelation();
  147. }
  148. /**
  149. * Uninstall
  150. * @return void
  151. */
  152. public static function uninstall()
  153. {
  154. self::uninstallByRelation();
  155. }
  156. /**
  157. * installByRelation
  158. * @return void
  159. */
  160. public static function installByRelation()
  161. {
  162. foreach (static::\$pathRelation as \$source => \$dest) {
  163. if (\$pos = strrpos(\$dest, '/')) {
  164. \$parent_dir = base_path().'/'.substr(\$dest, 0, \$pos);
  165. if (!is_dir(\$parent_dir)) {
  166. mkdir(\$parent_dir, 0777, true);
  167. }
  168. }
  169. //symlink(__DIR__ . "/\$source", base_path()."/\$dest");
  170. copy_dir(__DIR__ . "/\$source", base_path()."/\$dest");
  171. }
  172. }
  173. /**
  174. * uninstallByRelation
  175. * @return void
  176. */
  177. public static function uninstallByRelation()
  178. {
  179. foreach (static::\$pathRelation as \$source => \$dest) {
  180. /*if (is_link(base_path()."/\$dest")) {
  181. unlink(base_path()."/\$dest");
  182. }*/
  183. remove_dir(base_path()."/\$dest");
  184. }
  185. }
  186. }
  187. EOT;
  188. file_put_contents("$dest_dir/Install.php", $install_php_content);
  189. }
  190. }