['use App\Entities\Podcast;'], 'rssAfterChannel' => ['use App\Entities\Podcast;', 'use App\Libraries\SimpleRSSElement;'], 'rssBeforeItem' => ['use App\Entities\Episode;'], 'rssAfterItem' => ['use App\Entities\Episode;', 'use App\Libraries\SimpleRSSElement;'], 'siteHead' => [], ]; protected const HOOKS_METHODS = [ 'rssBeforeChannel' => ' public function rssBeforeChannel(Podcast $podcast): void { // YOUR CODE HERE }', 'rssAfterChannel' => ' public function rssAfterChannel(Podcast $podcast, SimpleRSSElement $channel): void { // YOUR CODE HERE }', 'rssBeforeItem' => ' public function rssBeforeItem(Episode $episode): void { // YOUR CODE HERE }', 'rssAfterItem' => ' public function rssAfterItem(Episode $episode, SimpleRSSElement $item): void { // YOUR CODE HERE }', 'siteHead' => ' public function siteHead(): void { // YOUR CODE HERE }', ]; /** * @var string */ protected $group = 'Plugins'; /** * @var string */ protected $name = 'plugins:create'; /** * @var string */ protected $description = 'Generates a new plugin folder based on a template.'; /** * Actually execute a command. * * @param list $params */ #[Override] public function run(array $params): void { $pluginName = CLI::prompt( 'Plugin name (/)', 'acme/hello-world', Manifest::VALIDATION_RULES['name'] ); CLI::newLine(); $description = CLI::prompt('Description', '', Manifest::VALIDATION_RULES['description']); CLI::newLine(); $license = CLI::prompt('License', 'UNLICENSED', Manifest::VALIDATION_RULES['license']); CLI::newLine(); $hooks = CLI::promptByMultipleKeys('Which hooks do you want to implement?', Plugins::HOOKS); $nameParts = explode('/', $pluginName); $vendor = $nameParts[0]; $name = $nameParts[1]; /** @var PluginsConfig $pluginsConfig */ $pluginsConfig = config('Plugins'); // 1. create plugin directory if not existent $pluginDirectory = $pluginsConfig->folder . $vendor . DIRECTORY_SEPARATOR . $name; if (! file_exists($pluginDirectory)) { mkdir($pluginDirectory, 0755, true); } // 2. get contents of templates $manifestTemplate = file_get_contents(__DIR__ . '/plugin-template/manifest.tpl.json'); if (! $manifestTemplate) { throw new Exception('Failed to get manifest template.'); } $pluginClassTemplate = file_get_contents(__DIR__ . '/plugin-template/Plugin.tpl.php'); if (! $pluginClassTemplate) { throw new Exception('Failed to get Plugin class template.'); } // 3. edit templates' contents $manifestContents = str_replace('"name": ""', '"name": "' . $pluginName . '"', $manifestTemplate); $manifestContents = str_replace( '"description": ""', '"description": "' . $description . '"', $manifestContents ); $manifestContents = str_replace('"license": ""', '"license": "' . $license . '"', $manifestContents); $manifestContents = str_replace( '"hooks": []', '"hooks": ["' . implode('", "', $hooks) . '"]', $manifestContents ); $pluginClassName = str_replace( ' ', '', ucwords(str_replace(['-', '_', '.'], ' ', $vendor . ' ' . $name)) . 'Plugin' ); $pluginClassContents = str_replace('class Plugin', 'class ' . $pluginClassName, $pluginClassTemplate); $allImports = []; $allMethods = []; foreach ($hooks as $hook) { $allImports = [...$allImports, ...self::HOOKS_IMPORTS[$hook]]; $allMethods = [...$allMethods, self::HOOKS_METHODS[$hook]]; } $imports = implode(PHP_EOL, array_unique($allImports)); $methods = implode(PHP_EOL . PHP_EOL, $allMethods); $pluginClassContents = str_replace('// IMPORTS_HERE', $imports, $pluginClassContents); $pluginClassContents = str_replace(' // HOOKS_HERE', $methods, $pluginClassContents); $manifest = $pluginDirectory . '/manifest.json'; $pluginClass = $pluginDirectory . '/Plugin.php'; if (! file_put_contents($manifest, $manifestContents)) { throw new Exception('Failed to create manifest.json file.'); } if (! file_put_contents($pluginClass, $pluginClassContents)) { throw new Exception('Failed to create Plugin class file.'); } CLI::newLine(1); CLI::write( sprintf('Plugin %s created in %s', CLI::color($pluginName, 'white'), CLI::color($pluginDirectory, 'white')), 'green' ); } }