| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- <?php
- declare(strict_types=1);
- namespace SixShop\MakerBundle\Generator;
- use Symfony\Component\Console\Style\SymfonyStyle;
- class PhpCodeGenerator
- {
- private string $templatesPath;
-
- /**
- * 排除的模板文件,这些模板由专门的生成器处理(一对多关系)
- */
- private array $excludedTemplates = [
- 'src/Model/Model.php.tpl.php', // 模型模板 - 由 MigrationMaker 中的 ModelGenerator 处理
- 'src/Entity/Entity.php.tpl.php', // 实体模板 - 由 MigrationMaker 中的 EntityGenerator 处理
- 'src/Controller', // 控制器目录 - 由专门的控制器生成器处理
- 'database/migrations', // 迁移文件夹 - 由 MigrationGenerator 处理
- 'route', // 路由模板目录 - 由 RouteUpdater 处理
- ];
- public function __construct()
- {
- $this->templatesPath = __DIR__ . '/../../templates';
- }
- /**
- * 生成PHP代码文件
- */
- public function generatePhpFiles(string $packageName, string $namespace, string $id, string $description, string $targetPath, SymfonyStyle $io): bool
- {
- try {
- $basePath = $this->getBasePath($packageName, $targetPath);
-
- // 准备模板变量
- $variables = [
- 'namespace' => $namespace,
- 'name' => $packageName,
- 'id' => $id,
- 'description' => $description
- ];
- // 获取所有需要生成的PHP文件模板
- $templateFiles = $this->getTemplateFiles();
-
- $io->section('生成PHP代码文件:');
-
- foreach ($templateFiles as $templateFile) {
- if (!$this->generateFileFromTemplate($templateFile, $basePath, $variables, $io)) {
- return false;
- }
- }
-
- $io->success('PHP代码文件生成完成!');
- return true;
-
- } catch (\Exception $e) {
- $io->error('生成PHP代码文件时发生错误: ' . $e->getMessage());
- return false;
- }
- }
- /**
- * 获取扩展基础路径
- */
- private function getBasePath(string $packageName, ?string $targetPath = null): string
- {
- if ($targetPath !== null) {
- return $targetPath;
- }
-
- // 默认路径
- $vendorDir = dirname(__DIR__, 5);
- return $vendorDir . '/runtime/extension/' . $packageName;
- }
- /**
- * 获取所有模板文件
- */
- private function getTemplateFiles(): array
- {
- $templates = [];
- $this->scanTemplateDirectory($this->templatesPath, '', $templates);
- return $templates;
- }
- /**
- * 递归扫描模板目录
- */
- private function scanTemplateDirectory(string $directory, string $relativePath, array &$templates): void
- {
- if (!is_dir($directory)) {
- return;
- }
- $items = scandir($directory);
- foreach ($items as $item) {
- if ($item === '.' || $item === '..') {
- continue;
- }
- $fullPath = $directory . '/' . $item;
- $currentRelativePath = $relativePath ? $relativePath . '/' . $item : $item;
- if (is_dir($fullPath)) {
- // 检查是否为排除的目录
- if ($this->isExcludedTemplate($currentRelativePath)) {
- continue;
- }
-
- // 递归扫描子目录
- $this->scanTemplateDirectory($fullPath, $currentRelativePath, $templates);
- } elseif (is_file($fullPath) && str_ends_with($item, '.php.tpl.php')) {
- // 检查是否为排除的模板文件
- if ($this->isExcludedTemplate($currentRelativePath)) {
- continue;
- }
-
- // 添加模板文件
- $templates[] = [
- 'template' => $currentRelativePath,
- 'target' => str_replace('.tpl.php', '', $currentRelativePath),
- 'fullPath' => $fullPath
- ];
- }
- }
- }
- /**
- * 从模板生成文件
- */
- private function generateFileFromTemplate(array $templateInfo, string $basePath, array $variables, SymfonyStyle $io): bool
- {
- $templatePath = $templateInfo['fullPath'];
- $targetPath = $basePath . '/' . $templateInfo['target'];
-
- // 确保目标目录存在
- $targetDir = dirname($targetPath);
- if (!is_dir($targetDir)) {
- if (!mkdir($targetDir, 0755, true)) {
- $io->error("无法创建目录: $targetDir");
- return false;
- }
- }
- // 如果文件已存在,询问是否覆盖
- if (file_exists($targetPath)) {
- if (!$io->confirm("文件已存在: {$templateInfo['target']},是否覆盖?", false)) {
- $io->text("跳过文件: {$templateInfo['target']}");
- return true;
- }
- }
- // 提取变量到当前作用域
- // 命名空间双斜杆需要改为单斜杠
- $namespace = str_replace('\\\\', '\\', $variables['namespace']);
- $name = $variables['name'];
- $id = $variables['id'];
- $description = $variables['description'];
- // 生成文件内容
- ob_start();
- include $templatePath;
- $content = ob_get_clean();
- // 写入文件
- if (file_put_contents($targetPath, $content) !== false) {
- $io->text("✓ 生成文件: {$templateInfo['target']}");
- return true;
- } else {
- $io->error("✗ 无法写入文件: {$templateInfo['target']}");
- return false;
- }
- }
- /**
- * 获取模板文件列表(用于预览)
- */
- public function getTemplateList(): array
- {
- return $this->getTemplateFiles();
- }
-
- /**
- * 检查模板是否在排除列表中
- */
- private function isExcludedTemplate(string $templatePath): bool
- {
- foreach ($this->excludedTemplates as $excludedPattern) {
- // 支持精确匹配和前缀匹配
- if ($templatePath === $excludedPattern || str_starts_with($templatePath, $excludedPattern)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * 设置排除的模板列表
- */
- public function setExcludedTemplates(array $excludedTemplates): self
- {
- $this->excludedTemplates = $excludedTemplates;
- return $this;
- }
-
- /**
- * 添加排除的模板
- */
- public function addExcludedTemplate(string $templatePath): self
- {
- if (!in_array($templatePath, $this->excludedTemplates)) {
- $this->excludedTemplates[] = $templatePath;
- }
- return $this;
- }
-
- /**
- * 移除排除的模板
- */
- public function removeExcludedTemplate(string $templatePath): self
- {
- $this->excludedTemplates = array_filter(
- $this->excludedTemplates,
- fn($excluded) => $excluded !== $templatePath
- );
- return $this;
- }
-
- /**
- * 获取当前排除的模板列表
- */
- public function getExcludedTemplates(): array
- {
- return $this->excludedTemplates;
- }
- }
|