ExtensionController.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. namespace Dcat\Admin\Controllers;
  3. use Dcat\Admin\Extension\Grid\ImportButton;
  4. use Dcat\Admin\Form;
  5. use Dcat\Admin\Grid;
  6. use Dcat\Admin\Layout\Content;
  7. use Dcat\Admin\Models\Repositories\Extension;
  8. use Dcat\Admin\Support\Helper;
  9. use Dcat\Admin\Support\StringOutput;
  10. use Dcat\Admin\Widgets\Alert;
  11. use Dcat\Admin\Widgets\Table;
  12. use Dcat\Admin\Widgets\Terminal;
  13. use Illuminate\Routing\Controller;
  14. use Illuminate\Support\Facades\Artisan;
  15. class ExtensionController extends Controller
  16. {
  17. use HasResourceActions;
  18. /**
  19. * Index interface.
  20. *
  21. * @param Content $content
  22. *
  23. * @return Content
  24. */
  25. public function index(Content $content)
  26. {
  27. $this->define();
  28. return $content
  29. ->title(admin_trans_label('Extensions'))
  30. ->description(trans('admin.list'))
  31. ->body($this->grid());
  32. }
  33. /**
  34. * @return \Illuminate\Http\JsonResponse
  35. */
  36. public function import()
  37. {
  38. $extension = request('id');
  39. if (! $extension) {
  40. return response()->json(['status' => false, 'messages' => 'Invalid extension hash.']);
  41. }
  42. $box = Alert::make()
  43. ->title("<span>php artisan admin:import $extension</span>")
  44. ->content(Terminal::call('admin:import', ['extension' => $extension, '--force' => '1'])->transparent())
  45. ->success()
  46. ->removable();
  47. return response()->json(['status' => true, 'content' => $box->render()]);
  48. }
  49. /**
  50. * Make a grid builder.
  51. *
  52. * @return Grid
  53. */
  54. protected function grid()
  55. {
  56. $grid = new Grid(new Extension());
  57. $grid->number();
  58. $grid->name;
  59. $grid->version;
  60. $grid->alias;
  61. $grid->description
  62. ->if(function () {
  63. return mb_strlen($this->description) > 14;
  64. })
  65. ->limit(14)
  66. ->expand(function ($expand) {
  67. if (! $this->description) {
  68. return;
  69. }
  70. return "<div style='padding:10px 20px'>{$this->description}</div>";
  71. });
  72. $grid->authors;
  73. $grid->enable->switch();
  74. $grid->imported;
  75. $view = trans('admin.view');
  76. $grid->config
  77. ->if(function () {
  78. return $this->config ? true : false;
  79. })
  80. ->display($view)
  81. ->expand($this->getExpandHandler('config'))
  82. ->else()
  83. ->emptyString();
  84. $grid->require
  85. ->if(function () {
  86. return $this->require ? true : false;
  87. })
  88. ->display($view)
  89. ->expand($this->getExpandHandler())
  90. ->else()
  91. ->emptyString();
  92. $grid->require_dev
  93. ->if(function () {
  94. return $this->require_dev ? true : false;
  95. })
  96. ->display($view)
  97. ->expand($this->getExpandHandler('require_dev'))
  98. ->else()
  99. ->emptyString();
  100. $grid->disablePagination();
  101. $grid->disableCreateButton();
  102. $grid->disableDeleteButton();
  103. $grid->disableBatchDelete();
  104. $grid->disableFilterButton();
  105. $grid->disableFilter();
  106. $grid->disableQuickEditButton();
  107. $grid->disableEditButton();
  108. $grid->disableDeleteButton();
  109. $grid->disableViewButton();
  110. $grid->actions(new ImportButton());
  111. $grid->quickCreate(function (Grid\Tools\QuickCreate $create) {
  112. $create->text('package_name')->required();
  113. $create->text('namespace')
  114. ->attribute('style', 'width:240px')
  115. ->required()
  116. ->default('Dcat\\Admin\\Extension\\:Name');
  117. });
  118. return $grid;
  119. }
  120. /**
  121. * Make a form builder.
  122. *
  123. * @return Form
  124. */
  125. public function form()
  126. {
  127. $form = new Form(new Extension());
  128. $form->text('package_name')->rules(function () {
  129. return [
  130. 'required',
  131. function ($attribute, $value, $fail) {
  132. if (! Helper::validateExtensionName($value)) {
  133. return $fail(
  134. "[$value] is not a valid package name, please input a name like \"vendor/name\""
  135. );
  136. }
  137. },
  138. ];
  139. });
  140. $form->text('namespace')->required();
  141. $form->hidden('enable');
  142. $form->saving(function (Form $form) {
  143. $package = $form->package_name;
  144. $namespace = $form->namespace;
  145. if ($package && $namespace) {
  146. $results = $this->createExtension($package, $namespace);
  147. return $form->success($results);
  148. }
  149. });
  150. return $form;
  151. }
  152. /**
  153. * 创建扩展.
  154. *
  155. * @return string
  156. */
  157. public function createExtension($package, $namespace)
  158. {
  159. $namespace = trim($namespace, '\\');
  160. $output = new StringOutput();
  161. Artisan::call('admin:extend', [
  162. 'extension' => $package,
  163. '--namespace' => $namespace,
  164. ], $output);
  165. return $output->getContent();
  166. }
  167. /**
  168. * @param string $key
  169. *
  170. * @return \Closure
  171. */
  172. protected function getExpandHandler($key = 'require')
  173. {
  174. return function () use ($key) {
  175. if (! $this->{$key}) {
  176. return;
  177. }
  178. $rows = [];
  179. foreach ((array) $this->{$key} as $k => $v) {
  180. $k = "<b class='text-80'>$k</b>";
  181. $rows[$k] = is_array($v) ? "<pre>{$v}</pre>" : $v;
  182. }
  183. return new Table($rows);
  184. };
  185. }
  186. /**
  187. * 字段显示定义.
  188. */
  189. protected function define()
  190. {
  191. $name = function ($v) {
  192. $url = $this->homepage;
  193. return "<a href='$url' target='_blank'>$v</a>";
  194. };
  195. $version = function ($v) {
  196. $this->version = $this->version ?: 'unknown';
  197. $style = in_array($this->version, ['dev-master', 'unknown']) ? 'default' : 'primary';
  198. return $this->version ? "<span class='label bg-$style'>{$this->version}</span>" : '';
  199. };
  200. $authors = function ($v) {
  201. if (! $v) {
  202. return;
  203. }
  204. foreach ($v as &$item) {
  205. $item = "<span class='text-80'>{$item['name']}</span> <<code>{$item['email']}</code>>";
  206. }
  207. return implode('<br/>', $v);
  208. };
  209. $imported = function ($v) {
  210. if (! $v) {
  211. $text = trans('admin.is_not_import');
  212. return "<label class='label label-default'>$text</label>";
  213. }
  214. return $this->imported_at;
  215. };
  216. Grid\Column::define('name', $name);
  217. Grid\Column::define('version', $version);
  218. Grid\Column::define('authors', $authors);
  219. Grid\Column::define('imported', $imported);
  220. }
  221. }