<?php
namespace YouHuJun\Tool\App\Console\Commands;
use YouHuJun\Tool\App\Exceptions\CommonException;
class GeneratorCommand
{
* @var string Facade 模板路径
*/
private string $facadeStubPath;
* @var string Service 模板路径
*/
private string $serviceStubPath;
* @var string 项目根目录
*/
private string $basePath;
* @var string 基础命名空间
*/
private string $baseNamespace;
public function __construct()
{
$this->basePath = dirname(__DIR__, 4);
$this->facadeStubPath = $this->basePath . '/src/App/Console/Commands/stubs/facade.stub';
$this->serviceStubPath = $this->basePath . '/src/App/Console/Commands/stubs/service.stub';
$this->baseNamespace = 'YouHuJun\\Tool\\App';
}
* 解析路径并执行对应操作
*
* @param string $path 路径,如: Wechat/Official/WechatOfficialWebAuth 或 Calendar
* @param string $description 描述信息(仅用于生成 Service)
* @return array 生成的文件路径
* @throws CommonException
*/
public function generate(string $path, string $description = ''): array
{
$path = trim($path, '/\\');
$path = str_replace('\\', '/', $path);
$parts = explode('/', $path);
if (count($parts) < 1) {
throw new CommonException('ParameterError');
}
$className = array_pop($parts);
$version = '';
if (!empty($parts) && preg_match('/^V\d+$/', $parts[0])) {
$version = array_shift($parts);
}
$modulePath = implode('/', $parts);
$generatedFiles[] = $this->generateFacadeFile($className, $modulePath, $version);
$generatedFiles[] = $this->generateServiceFile($className, $modulePath, $version, $description);
return $generatedFiles;
}
* 生成 Facade 文件
*/
private function generateFacadeFile(string $className, string $modulePath, string $version = 'V1'): string
{
$modulePath = trim($modulePath, '/\\');
$moduleNamespace = $modulePath ? '\\' . str_replace('/', '\\', $modulePath) : '';
$className = $this->sanitizeClassName($className);
$facadeClassName = $className;
$facadeClassName = preg_replace('/Facades?$/', '', $facadeClassName);
$facadeClassName .= 'Facade';
$serviceClassName = $className . 'Service';
$facadeDir = $this->basePath . '/src/App/Facades/' . $version . ($modulePath ? '/' . $modulePath : '');
$this->ensureDirectoryExists($facadeDir);
$facadeFile = $facadeDir . '/' . $facadeClassName . '.php';
if (file_exists($facadeFile)) {
throw new CommonException('FileExistsError');
}
$stub = file_get_contents($this->facadeStubPath);
$content = str_replace(
[
'{{Namespace}}',
'{{ModulePath}}',
'{{FacadeClass}}',
'{{ServiceClass}}',
],
[
$this->baseNamespace,
$moduleNamespace,
$facadeClassName,
$serviceClassName,
],
$stub
);
file_put_contents($facadeFile, $content);
return $facadeFile;
}
* 生成 Service 文件
*/
private function generateServiceFile(string $className, string $modulePath, string $version = 'V1', string $description = ''): string
{
$modulePath = trim($modulePath, '/\\');
$moduleNamespace = $modulePath ? '\\' . str_replace('/', '\\', $modulePath) : '';
$className = $this->sanitizeClassName($className);
$className = preg_replace('/Service$/', '', $className);
$className .= 'Service';
$serviceDir = $this->basePath . '/src/App/Services/' . $version . ($modulePath ? '/' . $modulePath : '');
$this->ensureDirectoryExists($serviceDir);
$serviceFile = $serviceDir . '/' . $className . '.php';
if (file_exists($serviceFile)) {
throw new CommonException('FileExistsError');
}
$stub = file_get_contents($this->serviceStubPath);
$content = str_replace(
[
'{{Namespace}}',
'{{ModulePath}}',
'{{ServiceClass}}',
'{{Description}}',
'{{Date}}',
'{{Year}}',
],
[
$this->baseNamespace,
$moduleNamespace,
$className,
$description ?: '自动生成的服务类',
date('Y-m-d H:i:s'),
date('Y'),
],
$stub
);
file_put_contents($serviceFile, $content);
return $serviceFile;
}
* 确保目录存在
*/
private function ensureDirectoryExists(string $directory): void
{
if (!is_dir($directory)) {
mkdir($directory, 0755, true);
}
}
* 清理类名
*/
private function sanitizeClassName(string $name): string
{
return preg_replace('/[^a-zA-Z0-9_]/', '', $name);
}
}