Make.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <?php
  2. /**
  3. * +----------------------------------------------------------------------
  4. * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  5. * +----------------------------------------------------------------------
  6. * | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  7. * +----------------------------------------------------------------------
  8. * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  9. * +----------------------------------------------------------------------
  10. * | Author: CRMEB Team <admin@crmeb.com>
  11. * +----------------------------------------------------------------------
  12. */
  13. namespace crmeb\services\crud;
  14. use crmeb\exceptions\CrudException;
  15. use think\App;
  16. use think\helper\Str;
  17. /**
  18. * 创建crud基类
  19. * Class Make
  20. * @author 等风来
  21. * @email 136327134@qq.com
  22. * @date 2023/3/13
  23. * @package crmeb\services\crud
  24. */
  25. abstract class Make
  26. {
  27. /**
  28. * 名称
  29. * @var string
  30. */
  31. protected $name = '';
  32. /**
  33. * 文件类型
  34. * @var string
  35. */
  36. protected $fileMime = 'php';
  37. /**
  38. * 文件全部路径
  39. * @var string
  40. */
  41. protected $filePathName = null;
  42. /**
  43. * @var string
  44. */
  45. protected $fileBasePath;
  46. /**
  47. * 变量名称
  48. * @var array
  49. */
  50. protected $var = [];
  51. /**
  52. * 内容
  53. * @var array
  54. */
  55. protected $value = [];
  56. /**
  57. * @var bool
  58. */
  59. protected $isMake = true;
  60. /**
  61. * 后台前端模板根路径
  62. * @var string
  63. */
  64. protected $adminTemplatePath;
  65. /**
  66. * 默认保存路径
  67. * @var string
  68. */
  69. protected $basePath;
  70. /**
  71. * 默认文件夹
  72. * @var string
  73. */
  74. protected $baseDir;
  75. /**
  76. * @var
  77. */
  78. protected $app;
  79. /**
  80. * Make constructor.
  81. * @param App $app
  82. */
  83. public function __construct(App $app)
  84. {
  85. $this->app = $app;
  86. $this->adminTemplatePath = self::adminTemplatePath();
  87. $this->basePath = $this->app->getRootPath();
  88. $this->baseDir = $this->setBaseDir();
  89. $this->var = $this->authDrawVar();
  90. $this->value = $this->drawValueKeys();
  91. $this->setDefaultValue();
  92. }
  93. /**
  94. * @return string
  95. * @author 等风来
  96. * @email 136327134@qq.com
  97. * @date 2023/4/11
  98. */
  99. public static function adminTemplatePath()
  100. {
  101. return config('app.admin_template_path');
  102. }
  103. /**
  104. * 设置默认保存目录
  105. * @author 等风来
  106. * @email 136327134@qq.com
  107. * @date 2023/4/4
  108. */
  109. protected function setBaseDir(): string
  110. {
  111. return 'crud';
  112. }
  113. /**
  114. * 获取保存文件的目录
  115. * @param string $path
  116. * @return string
  117. * @author 等风来
  118. * @email 136327134@qq.com
  119. * @date 2023/4/4
  120. */
  121. protected function getBasePath(string $path = '')
  122. {
  123. //替换成本地路径格式
  124. $path = str_replace('/', DS, $path);
  125. $pathAttr = explode(DS, $path);
  126. $basePathAttr = explode(DS, $this->baseDir);
  127. //替换掉和基础目录相同的
  128. if (count($pathAttr) > 1) {
  129. $newsPath = array_merge(array_diff($basePathAttr, $pathAttr))[0] ?? '';
  130. if ($newsPath !== 'crud') {
  131. $path = $newsPath;
  132. } else {
  133. $this->baseDir = '';
  134. }
  135. }
  136. //多个斜杠的替换成一个
  137. $this->fileBasePath = str_replace(DS . DS, DS, $this->basePath . ($this->baseDir ? $this->baseDir . DS : '') . ($path ? $path . DS : ''));
  138. return $this->fileBasePath;
  139. }
  140. /**
  141. * @return string
  142. * @author 等风来
  143. * @email 136327134@qq.com
  144. * @date 2023/4/7
  145. */
  146. public function getFileBasePath()
  147. {
  148. return $this->fileBasePath;
  149. }
  150. /**
  151. * 设置文件保存就路径名称
  152. * @param string $filePathName
  153. * @return $this
  154. * @author 等风来
  155. * @email 136327134@qq.com
  156. * @date 2023/4/7
  157. */
  158. public function setFilePathName(string $filePathName = '')
  159. {
  160. if ($filePathName) {
  161. $this->filePathName = $filePathName;
  162. }
  163. return $this;
  164. }
  165. /**
  166. * 生成tab
  167. * @param int $num
  168. * @return string
  169. * @author 等风来
  170. * @email 136327134@qq.com
  171. * @date 2023/3/29
  172. */
  173. public function tab(int $num = 1): string
  174. {
  175. return str_pad('', 4 * $num);
  176. }
  177. /**
  178. * 是否生成文件
  179. * @param bool $isMake
  180. * @return $this
  181. * @author 等风来
  182. * @email 136327134@qq.com
  183. * @date 2023/4/3
  184. */
  185. public function isMake(bool $isMake = true)
  186. {
  187. $this->isMake = $isMake;
  188. return $this;
  189. }
  190. /**
  191. * 执行创建
  192. * @return mixed|void
  193. * @author 等风来
  194. * @email 136327134@qq.com
  195. * @date 2023/3/13
  196. */
  197. public function handle(string $name, array $options = [])
  198. {
  199. $path = $options['path'] ?? '';
  200. [$nameData, $content] = $this->getStubContent($name);
  201. $this->value['name'] = $nameData;
  202. if (isset($this->value['nameCamel']) && !$this->value['nameCamel']) {
  203. $this->value['nameCamel'] = Str::studly($name);
  204. }
  205. if (isset($this->value['path'])) {
  206. $this->value['path'] = $this->getfolderPath($path);
  207. }
  208. $contentStr = str_replace($this->var, $this->value, $content);
  209. $filePath = $this->getFilePathName($path, $this->value['nameCamel']);
  210. return [
  211. $this->makeFile($filePath, $contentStr),
  212. $this->filePathName ?: $filePath,
  213. $this->value['path'] ?? '',
  214. $this->value['nameCamel']
  215. ];
  216. }
  217. /**
  218. * 模板文件配置
  219. * @param string $type
  220. * @return mixed
  221. * @author 等风来
  222. * @email 136327134@qq.com
  223. * @date 2023/3/13
  224. */
  225. abstract protected function getStub(string $type = '');
  226. /**
  227. * 自动获取模板变量
  228. * @author 等风来
  229. * @email 136327134@qq.com
  230. * @date 2023/3/29
  231. */
  232. protected function authDrawVar(): array
  233. {
  234. $content = file_get_contents($this->getStub());
  235. $pattern = '/\{\%+[a-zA-Z0-9_-]+\%\}/';
  236. preg_match_all($pattern, $content, $var);
  237. $varData = $var[0] ?? [];
  238. $varData = array_unique($varData);
  239. return $varData;
  240. }
  241. /**
  242. * 提取value key
  243. * @author 等风来
  244. * @email 136327134@qq.com
  245. * @date 2023/3/29
  246. */
  247. protected function drawValueKeys(): array
  248. {
  249. $data = [];
  250. foreach ($this->var as $value) {
  251. $data[str_replace(['{%', '%}'], '', $value)] = '';
  252. }
  253. return $data;
  254. }
  255. /**
  256. * 设置默认值
  257. * @author 等风来
  258. * @email 136327134@qq.com
  259. * @date 2023/3/13
  260. */
  261. protected function setDefaultValue()
  262. {
  263. if (isset($this->value['year'])) {
  264. $this->value['year'] = date('Y');
  265. }
  266. if (isset($this->value['time'])) {
  267. $this->value['time'] = date('Y/m/d H:i:s');
  268. }
  269. if (isset($this->value['date'])) {
  270. $this->value['date'] = date('Y/m/d');
  271. }
  272. }
  273. /**
  274. * 提取模板文件
  275. * @param string $name
  276. * @return array
  277. * @author 等风来
  278. * @email 136327134@qq.com
  279. * @date 2023/3/13
  280. */
  281. protected function getStubContent(string $name, string $type = '')
  282. {
  283. $stub = file_get_contents($this->getStub($type));
  284. $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
  285. $class = str_replace($namespace . '\\', '', $name);
  286. return [$class, $stub];
  287. }
  288. /**
  289. * 获取文件路径
  290. * @param string $path
  291. * @param string $name
  292. * @return string
  293. * @author 等风来
  294. * @email 136327134@qq.com
  295. * @date 2023/3/13
  296. */
  297. protected function getFilePathName(string $path, string $name): string
  298. {
  299. $path = ltrim(str_replace('\\', '/', $path), '/');
  300. return $this->getBasePath($path) . $name . ucwords($this->name) . '.' . $this->fileMime;
  301. }
  302. /**
  303. * @param string $path
  304. * @return mixed|string|null
  305. * @author 等风来
  306. * @email 136327134@qq.com
  307. * @date 2023/3/13
  308. */
  309. protected function getfolderPath(string $path)
  310. {
  311. $path = $path ?: $this->filePathName;
  312. $path = str_replace([$this->basePath, $this->baseDir], '', $path);
  313. $path = ltrim(str_replace('\\', '/', $path), '/');
  314. $pathArr = explode('/', $path);
  315. array_pop($pathArr);
  316. if ($pathArr) {
  317. return '\\' . implode('\\', $pathArr);
  318. } else {
  319. return '';
  320. }
  321. }
  322. /**
  323. * 获取保存文件路径
  324. * @param string $name
  325. * @return string
  326. * @author 等风来
  327. * @email 136327134@qq.com
  328. * @date 2023/3/13
  329. */
  330. protected function getPathName(string $name): string
  331. {
  332. $name = str_replace('app\\', '', $name);
  333. return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
  334. }
  335. /**
  336. * 获取类名
  337. * @param string $name
  338. * @return string
  339. * @author 等风来
  340. * @email 136327134@qq.com
  341. * @date 2023/3/13
  342. */
  343. protected function getClassName(string $name): string
  344. {
  345. if (strpos($name, '\\') !== false) {
  346. return $name;
  347. }
  348. if (strpos($name, '@')) {
  349. [$app, $name] = explode('@', $name);
  350. } else {
  351. $app = '';
  352. }
  353. if (strpos($name, '/') !== false) {
  354. $name = str_replace('/', '\\', $name);
  355. }
  356. return $this->getNamespace($app) . '\\' . $name;
  357. }
  358. /**
  359. * 获取命名空间名
  360. * @param string $app
  361. * @return string
  362. * @author 等风来
  363. * @email 136327134@qq.com
  364. * @date 2023/3/13
  365. */
  366. protected function getNamespace(string $app): string
  367. {
  368. return 'app' . ($app ? '\\' . $app : '');
  369. }
  370. /**
  371. * 执行创建文件
  372. * @return string
  373. * @author 等风来
  374. * @email 136327134@qq.com
  375. * @date 2023/3/13
  376. */
  377. protected function makeFile(string $pathname, string $content)
  378. {
  379. $pathname = $this->filePathName ?: $pathname;
  380. $content = str_replace('', '', $content);
  381. if ($this->isMake) {
  382. if (is_file($pathname)) {
  383. throw new CrudException($this->name . ':' . $pathname . ' already exists!');
  384. }
  385. try {
  386. if (!is_dir(dirname($pathname))) {
  387. mkdir(dirname($pathname), 0755, true);
  388. }
  389. } catch (\Throwable $e) {
  390. throw new CrudException('CRUD创建目录报错,无法创建:' . dirname($pathname));
  391. }
  392. try {
  393. file_put_contents($pathname, $content);
  394. } catch (\Throwable $e) {
  395. throw new CrudException('CRUD生成文件报错,无法写入:' . $pathname);
  396. }
  397. }
  398. return $content;
  399. }
  400. }