├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── resources └── views │ ├── artisan.blade.php │ ├── database.blade.php │ └── scaffold.blade.php └── src ├── Controllers ├── RouteController.php ├── ScaffoldController.php └── TerminalController.php ├── Helpers.php ├── HelpersServiceProvider.php └── Scaffold ├── ControllerCreator.php ├── MigrationCreator.php ├── ModelCreator.php └── stubs ├── controller.stub ├── create.stub └── model.stub /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | phpunit.phar 3 | /vendor 4 | composer.phar 5 | composer.lock 6 | *.project 7 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jens Segers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Helpers for laravel-admin 2 | ========================= 3 | 4 | [](https://styleci.io/repos/97900966) 5 | [](https://packagist.org/packages/laravel-admin-ext/helpers) 6 | [](https://packagist.org/packages/laravel-admin-ext/helpers) 7 | []() 8 | 9 | [Documentation](http://laravel-admin.org/docs/#/en/extension-helpers) | [中文文档](http://laravel-admin.org/docs/#/zh/extension-helpers) 10 | 11 | DEMO [helpers](http://demo.laravel-admin.org/helpers/scaffold) 12 | 13 | Login using `admin/admin` 14 | 15 | ## Installation 16 | 17 | ``` 18 | // For laravel-admin 1.x 19 | $ composer require "laravel-admin-ext/helpers:1.*" 20 | 21 | // For laravel-admin 2.x 22 | $ composer require "laravel-admin-ext/helpers:2.*" 23 | ``` 24 | 25 | Import menu items. 26 | 27 | ```shell 28 | $ php artisan admin:import helpers 29 | ``` 30 | 31 | ## Usage 32 | 33 | See [wiki](http://laravel-admin.org/docs/#/en/extension-helpers?id=helpers) 34 | 35 | ## Donate 36 | 37 | > Help keeping the project development going, by donating a little. Thanks in advance. 38 | 39 | [](https://www.paypal.me/zousong) 40 | 41 |  42 | 43 | License 44 | ------------ 45 | Licensed under [The MIT License (MIT)](LICENSE). 46 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel-admin-ext/helpers", 3 | "description": "Helpers extension for laravel-admin", 4 | "type": "library", 5 | "keywords": ["laravel-admin", "helpers"], 6 | "homepage": "https://github.com/laravel-admin-extensions/helpers", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "z-song", 11 | "email": "zosong@126.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=7.0.0", 16 | "encore/laravel-admin": "~1.6" 17 | }, 18 | "require-dev": { 19 | "phpunit/phpunit": "~6.0" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Encore\\Admin\\Helpers\\": "src/" 24 | } 25 | }, 26 | "extra": { 27 | "laravel": { 28 | "providers": [ 29 | "Encore\\Admin\\Helpers\\HelpersServiceProvider" 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /resources/views/artisan.blade.php: -------------------------------------------------------------------------------- 1 | 119 | 120 |
$0', $uri);
38 | })->sortable();
39 |
40 | $grid->name();
41 |
42 | $grid->action()->display(function ($uri) {
43 | return preg_replace('/@.+/', '$0
', $uri);
44 | });
45 | $grid->middleware()->badge('yellow');
46 |
47 | $grid->disablePagination();
48 | $grid->disableRowSelector();
49 | $grid->disableActions();
50 | $grid->disableCreation();
51 | $grid->disableExport();
52 |
53 | $grid->filter(function ($filter) {
54 | $filter->disableIdFilter();
55 | $filter->equal('action');
56 | $filter->equal('uri');
57 | });
58 | }));
59 | });
60 | }
61 |
62 | protected function getModel()
63 | {
64 | return new class() extends Model {
65 | protected $routes;
66 |
67 | protected $where = [];
68 |
69 | public function setRoutes($routes)
70 | {
71 | $this->routes = $routes;
72 |
73 | return $this;
74 | }
75 |
76 | public function where($column, $condition)
77 | {
78 | $this->where[$column] = trim($condition);
79 |
80 | return $this;
81 | }
82 |
83 | public function orderBy()
84 | {
85 | return $this;
86 | }
87 |
88 | public function get()
89 | {
90 | $this->routes = collect($this->routes)->filter(function ($route) {
91 | foreach ($this->where as $column => $condition) {
92 | if (!Str::contains($route[$column], $condition)) {
93 | return false;
94 | }
95 | }
96 |
97 | return true;
98 | })->all();
99 |
100 | $instance = $this->newModelInstance();
101 |
102 | return $instance->newCollection(array_map(function ($item) use ($instance) {
103 | return $instance->newFromBuilder($item);
104 | }, $this->routes));
105 | }
106 | };
107 | }
108 |
109 | public function getRoutes()
110 | {
111 | $routes = app('router')->getRoutes();
112 |
113 | $routes = collect($routes)->map(function ($route) {
114 | return $this->getRouteInformation($route);
115 | })->all();
116 |
117 | if ($sort = request('_sort')) {
118 | $routes = $this->sortRoutes($sort, $routes);
119 | }
120 |
121 | return array_filter($routes);
122 | }
123 |
124 | /**
125 | * Get the route information for a given route.
126 | *
127 | * @param \Illuminate\Routing\Route $route
128 | *
129 | * @return array
130 | */
131 | protected function getRouteInformation(Route $route)
132 | {
133 | return [
134 | 'host' => $route->domain(),
135 | 'method' => $route->methods(),
136 | 'uri' => $route->uri(),
137 | 'name' => $route->getName(),
138 | 'action' => $route->getActionName(),
139 | 'middleware' => $this->getRouteMiddleware($route),
140 | ];
141 | }
142 |
143 | /**
144 | * Sort the routes by a given element.
145 | *
146 | * @param string $sort
147 | * @param array $routes
148 | *
149 | * @return array
150 | */
151 | protected function sortRoutes($sort, $routes)
152 | {
153 | return Arr::sort($routes, function ($route) use ($sort) {
154 | return $route[$sort];
155 | });
156 | }
157 |
158 | /**
159 | * Get before filters.
160 | *
161 | * @param \Illuminate\Routing\Route $route
162 | *
163 | * @return string
164 | */
165 | protected function getRouteMiddleware($route)
166 | {
167 | return collect($route->gatherMiddleware())->map(function ($middleware) {
168 | return $middleware instanceof \Closure ? 'Closure' : $middleware;
169 | });
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/Controllers/ScaffoldController.php:
--------------------------------------------------------------------------------
1 | header('Scaffold');
22 |
23 | $dbTypes = [
24 | 'string', 'integer', 'text', 'float', 'double', 'decimal', 'boolean', 'date', 'time',
25 | 'dateTime', 'timestamp', 'char', 'mediumText', 'longText', 'tinyInteger', 'smallInteger',
26 | 'mediumInteger', 'bigInteger', 'unsignedTinyInteger', 'unsignedSmallInteger', 'unsignedMediumInteger',
27 | 'unsignedInteger', 'unsignedBigInteger', 'enum', 'json', 'jsonb', 'dateTimeTz', 'timeTz',
28 | 'timestampTz', 'nullableTimestamps', 'binary', 'ipAddress', 'macAddress',
29 | ];
30 |
31 | $action = URL::current();
32 |
33 | $content->row(view('laravel-admin-helpers::scaffold', compact('dbTypes', 'action')));
34 | });
35 | }
36 |
37 | public function store(Request $request)
38 | {
39 | $paths = [];
40 | $message = '';
41 |
42 | try {
43 |
44 | // 1. Create model.
45 | if (in_array('model', $request->get('create'))) {
46 | $modelCreator = new ModelCreator($request->get('table_name'), $request->get('model_name'));
47 |
48 | $paths['model'] = $modelCreator->create(
49 | $request->get('primary_key'),
50 | $request->get('timestamps') == 'on',
51 | $request->get('soft_deletes') == 'on'
52 | );
53 | }
54 |
55 | // 2. Create controller.
56 | if (in_array('controller', $request->get('create'))) {
57 | $paths['controller'] = (new ControllerCreator($request->get('controller_name')))
58 | ->create($request->get('model_name'), $request->get('fields'));
59 | }
60 |
61 | // 3. Create migration.
62 | if (in_array('migration', $request->get('create'))) {
63 | $migrationName = 'create_'.$request->get('table_name').'_table';
64 |
65 | $paths['migration'] = (new MigrationCreator(app('files')))->buildBluePrint(
66 | $request->get('fields'),
67 | $request->get('primary_key', 'id'),
68 | $request->get('timestamps') == 'on',
69 | $request->get('soft_deletes') == 'on'
70 | )->create($migrationName, database_path('migrations'), $request->get('table_name'));
71 | }
72 |
73 | // 4. Run migrate.
74 | if (in_array('migrate', $request->get('create'))) {
75 | Artisan::call('migrate');
76 | $message = Artisan::output();
77 | }
78 | } catch (\Exception $exception) {
79 |
80 | // Delete generated files if exception thrown.
81 | app('files')->delete($paths);
82 |
83 | return $this->backWithException($exception);
84 | }
85 |
86 | return $this->backWithSuccess($paths, $message);
87 | }
88 |
89 | protected function backWithException(\Exception $exception)
90 | {
91 | $error = new MessageBag([
92 | 'title' => 'Error',
93 | 'message' => $exception->getMessage(),
94 | ]);
95 |
96 | return back()->withInput()->with(compact('error'));
97 | }
98 |
99 | protected function backWithSuccess($paths, $message)
100 | {
101 | $messages = [];
102 |
103 | foreach ($paths as $name => $path) {
104 | $messages[] = ucfirst($name).": $path";
105 | }
106 |
107 | $messages[] = "
$message";
108 |
109 | $success = new MessageBag([
110 | 'title' => 'Success',
111 | 'message' => implode('
', $messages),
112 | ]);
113 |
114 | return back()->with(compact('success'));
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/Controllers/TerminalController.php:
--------------------------------------------------------------------------------
1 | header('Artisan terminal');
27 |
28 | $content->row(view('laravel-admin-helpers::artisan', ['commands' => $this->organizedCommands()]));
29 | });
30 | }
31 |
32 | public function runArtisan()
33 | {
34 | $command = Request::get('c', 'list');
35 |
36 | // If Exception raised.
37 | if (1 === Artisan::handle(
38 | new ArgvInput(explode(' ', 'artisan '.trim($command))),
39 | $output = new StringOutput()
40 | )) {
41 | return $this->renderException(new Exception($output->getContent()));
42 | }
43 |
44 | return sprintf('%s
', $output->getContent());
45 | }
46 |
47 | public function database()
48 | {
49 | return Admin::content(function (Content $content) {
50 | $content->header('Database terminal');
51 |
52 | $content->row(view('laravel-admin-helpers::database', ['connections' => $this->connections()]));
53 | });
54 | }
55 |
56 | public function runDatabase()
57 | {
58 | $query = Request::get('q');
59 |
60 | $connection = Request::get('c', config('database.default'));
61 |
62 | return $this->dispatchQuery($connection, $query);
63 | }
64 |
65 | protected function getDumpedHtml($var)
66 | {
67 | ob_start();
68 |
69 | dump($var);
70 |
71 | $content = ob_get_contents();
72 |
73 | ob_get_clean();
74 |
75 | return substr($content, strpos($content, ' $_) {
83 | $dbs[] = [
84 | 'option' => $name,
85 | 'value' => "db:$name",
86 | 'selected' => $name == config('database.default'),
87 | ];
88 | }
89 |
90 | $connections = array_filter(config('database.redis'), function ($config) {
91 | return is_array($config);
92 | });
93 |
94 | foreach ($connections as $name => $_) {
95 | $redis[] = [
96 | 'value' => "redis:$name",
97 | 'option' => $name,
98 | ];
99 | }
100 |
101 | return compact('dbs', 'redis');
102 | }
103 |
104 | protected function table(array $headers, $rows, $style = 'default')
105 | {
106 | $output = new StringOutput();
107 |
108 | $table = new Table($output);
109 |
110 | if ($rows instanceof Arrayable) {
111 | $rows = $rows->toArray();
112 | }
113 |
114 | $table->setHeaders($headers)->setRows($rows)->setStyle($style)->render();
115 |
116 | return $output->getContent();
117 | }
118 |
119 | protected function dispatchQuery($connection, $query)
120 | {
121 | list($type, $connection) = explode(':', $connection);
122 |
123 | if ($type == 'redis') {
124 | return $this->execRedisCommand($connection, $query);
125 | }
126 |
127 | $config = config('database.connections.'.$connection);
128 |
129 | if ($config['driver'] == 'mongodb') {
130 | return $this->execMongodbQuery($config, $query);
131 | }
132 |
133 | /* @var \Illuminate\Database\Connection $connection */
134 | $connection = DB::connection($connection);
135 |
136 | $connection->enableQueryLog();
137 |
138 | try {
139 | $result = $connection->select(str_replace([';', "\G"], '', $query));
140 | } catch (Exception $exception) {
141 | return $this->renderException($exception);
142 | }
143 |
144 | $log = current($connection->getQueryLog());
145 |
146 | if (empty($result)) {
147 | return sprintf("Empty set (%s sec)
\r\n", number_format($log['time'] / 1000, 2));
148 | }
149 |
150 | $result = json_decode(json_encode($result), true);
151 |
152 | if (Str::contains($query, "\G")) {
153 | return $this->getDumpedHtml($result);
154 | }
155 |
156 | return sprintf(
157 | "%s \n%d %s in set (%s sec)
\r\n",
158 | $this->table(array_keys(current($result)), $result),
159 | count($result),
160 | count($result) == 1 ? 'row' : 'rows',
161 | number_format($log['time'] / 1000, 2)
162 | );
163 | }
164 |
165 | protected function execMongodbQuery($config, $query)
166 | {
167 | if (Str::contains($query, '.find(') && !Str::contains($query, '.toArray(')) {
168 | $query .= '.toArray()';
169 | }
170 |
171 | $manager = new Manager("mongodb://{$config['host']}:{$config['port']}");
172 | $command = new Command(['eval' => $query]);
173 |
174 | try {
175 | $cursor = $manager->executeCommand($config['database'], $command);
176 | } catch (Exception $exception) {
177 | return $this->renderException($exception);
178 | }
179 |
180 | $result = $cursor->toArray()[0];
181 |
182 | $result = json_decode(json_encode($result), true);
183 |
184 | if (isset($result['errmsg'])) {
185 | return $this->renderException(new Exception($result['errmsg']));
186 | }
187 |
188 | return $this->getDumpedHtml($result['retval']);
189 | }
190 |
191 | protected function execRedisCommand($connection, $command)
192 | {
193 | $command = explode(' ', $command);
194 |
195 | try {
196 | $result = Redis::connection($connection)->executeRaw($command);
197 | } catch (Exception $exception) {
198 | return $this->renderException($exception);
199 | }
200 |
201 | if (is_string($result) && Str::startsWith($result, ['ERR ', 'WRONGTYPE '])) {
202 | return $this->renderException(new Exception($result));
203 | }
204 |
205 | return $this->getDumpedHtml($result);
206 | }
207 |
208 | protected function organizedCommands()
209 | {
210 | $commands = array_keys(Artisan::all());
211 |
212 | $groups = $others = [];
213 |
214 | foreach ($commands as $command) {
215 | $parts = explode(':', $command);
216 |
217 | if (isset($parts[1])) {
218 | $groups[$parts[0]][] = $command;
219 | } else {
220 | $others[] = $command;
221 | }
222 | }
223 |
224 | foreach ($groups as $key => $group) {
225 | if (count($group) === 1) {
226 | $others[] = $group[0];
227 |
228 | unset($groups[$key]);
229 | }
230 | }
231 |
232 | ksort($groups);
233 | sort($others);
234 |
235 | return compact('groups', 'others');
236 | }
237 |
238 | protected function renderException(Exception $exception)
239 | {
240 | return sprintf(
241 | " %s",
242 | str_replace("\n", '
', $exception->getMessage())
243 | );
244 | }
245 | }
246 |
247 | class StringOutput extends Output
248 | {
249 | public $output = '';
250 |
251 | public function clear()
252 | {
253 | $this->output = '';
254 | }
255 |
256 | protected function doWrite($message, $newline)
257 | {
258 | $this->output .= $message.($newline ? "\n" : '');
259 | }
260 |
261 | public function getContent()
262 | {
263 | return trim($this->output);
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/src/Helpers.php:
--------------------------------------------------------------------------------
1 | get('helpers/terminal/database', 'Encore\Admin\Helpers\Controllers\TerminalController@database');
33 | $router->post('helpers/terminal/database', 'Encore\Admin\Helpers\Controllers\TerminalController@runDatabase');
34 | $router->get('helpers/terminal/artisan', 'Encore\Admin\Helpers\Controllers\TerminalController@artisan');
35 | $router->post('helpers/terminal/artisan', 'Encore\Admin\Helpers\Controllers\TerminalController@runArtisan');
36 | $router->get('helpers/scaffold', 'Encore\Admin\Helpers\Controllers\ScaffoldController@index');
37 | $router->post('helpers/scaffold', 'Encore\Admin\Helpers\Controllers\ScaffoldController@store');
38 | $router->get('helpers/routes', 'Encore\Admin\Helpers\Controllers\RouteController@index');
39 | });
40 | }
41 |
42 | public static function import()
43 | {
44 | $lastOrder = Menu::max('order') ?: 0;
45 |
46 | $root = [
47 | 'parent_id' => 0,
48 | 'order' => $lastOrder++,
49 | 'title' => 'Helpers',
50 | 'icon' => 'fa-gears',
51 | 'uri' => '',
52 | ];
53 |
54 | $root = Menu::create($root);
55 |
56 | $menus = [
57 | [
58 | 'title' => 'Scaffold',
59 | 'icon' => 'fa-keyboard-o',
60 | 'uri' => 'helpers/scaffold',
61 | ],
62 | [
63 | 'title' => 'Database terminal',
64 | 'icon' => 'fa-database',
65 | 'uri' => 'helpers/terminal/database',
66 | ],
67 | [
68 | 'title' => 'Laravel artisan',
69 | 'icon' => 'fa-terminal',
70 | 'uri' => 'helpers/terminal/artisan',
71 | ],
72 | [
73 | 'title' => 'Routes',
74 | 'icon' => 'fa-list-alt',
75 | 'uri' => 'helpers/routes',
76 | ],
77 | ];
78 |
79 | foreach ($menus as $menu) {
80 | $menu['parent_id'] = $root->id;
81 | $menu['order'] = $lastOrder++;
82 |
83 | Menu::create($menu);
84 | }
85 |
86 | parent::createPermission('Admin helpers', 'ext.helpers', 'helpers/*');
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/HelpersServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadViewsFrom(__DIR__.'/../resources/views', 'laravel-admin-helpers');
15 |
16 | Helpers::boot();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Scaffold/ControllerCreator.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 |
37 | $this->files = $files ?: app('files');
38 | }
39 |
40 | /**
41 | * Create a controller.
42 | *
43 | * @param string $model
44 | *
45 | * @throws \Exception
46 | *
47 | * @return string
48 | */
49 | public function create($model, $fields)
50 | {
51 | $path = $this->getpath($this->name);
52 |
53 | if ($this->files->exists($path)) {
54 | throw new \Exception("Controller [$this->name] already exists!");
55 | }
56 |
57 | $this->generateGridField($fields);
58 |
59 | $this->generateShowField($fields);
60 |
61 | $this->generateFormField($fields);
62 |
63 | $stub = $this->files->get($this->getStub());
64 |
65 | $this->files->put($path, $this->replace($stub, $this->name, $model));
66 |
67 | return $path;
68 | }
69 |
70 | /**
71 | * @param string $stub
72 | * @param string $name
73 | * @param string $model
74 | *
75 | * @return string
76 | */
77 | protected function replace($stub, $name, $model)
78 | {
79 | $stub = $this->replaceClass($stub, $name);
80 |
81 | return str_replace(
82 | ['DummyModelNamespace', 'DummyModel', 'DummyGridField', 'DummyShowField', 'DummyFormField'],
83 | [$model, class_basename($model), $this->DummyGridField, $this->DummyShowField, $this->DummyFormField],
84 | $stub
85 | );
86 | }
87 |
88 | /**
89 | * Get controller namespace from giving name.
90 | *
91 | * @param string $name
92 | *
93 | * @return string
94 | */
95 | protected function getNamespace($name)
96 | {
97 | return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
98 | }
99 |
100 | /**
101 | * Replace the class name for the given stub.
102 | *
103 | * @param string $stub
104 | * @param string $name
105 | *
106 | * @return string
107 | */
108 | protected function replaceClass($stub, $name)
109 | {
110 | $class = str_replace($this->getNamespace($name).'\\', '', $name);
111 |
112 | return str_replace(['DummyClass', 'DummyNamespace'], [$class, $this->getNamespace($name)], $stub);
113 | }
114 |
115 | /**
116 | * Get file path from giving controller name.
117 | *
118 | * @param $name
119 | *
120 | * @return string
121 | */
122 | public function getPath($name)
123 | {
124 | $segments = explode('\\', $name);
125 |
126 | array_shift($segments);
127 |
128 | return app_path(implode('/', $segments)).'.php';
129 | }
130 |
131 | /**
132 | * Get stub file path.
133 | *
134 | * @return string
135 | */
136 | public function getStub()
137 | {
138 | return __DIR__.'/stubs/controller.stub';
139 | }
140 |
141 | public function generateFormField($fields = [])
142 | {
143 | $fields = array_filter($fields, function ($field) {
144 | return isset($field['name']) && !empty($field['name']);
145 | });
146 |
147 | if (empty($fields)) {
148 | throw new \Exception('Table fields can\'t be empty');
149 | }
150 |
151 | foreach ($fields as $field) {
152 | $rows[] = "\$form->text('{$field['name']}', '{$field['name']}');\n";
153 | }
154 |
155 | $this->DummyFormField = trim(implode(str_repeat(' ', 8), $rows), "\n");
156 |
157 | return $this;
158 | }
159 |
160 | public function generateShowField($fields = [])
161 | {
162 | $fields = array_filter($fields, function ($field) {
163 | return isset($field['name']) && !empty($field['name']);
164 | });
165 |
166 | if (empty($fields)) {
167 | throw new \Exception('Table fields can\'t be empty');
168 | }
169 | foreach ($fields as $field) {
170 | $rows[] = "\$show->{$field['name']}('{$field['name']}');\n";
171 | }
172 |
173 | $this->DummyShowField = trim(implode(str_repeat(' ', 8), $rows), "\n");
174 |
175 | return $this;
176 | }
177 |
178 | public function generateGridField($fields = [])
179 | {
180 | $fields = array_filter($fields, function ($field) {
181 | return isset($field['name']) && !empty($field['name']);
182 | });
183 |
184 | if (empty($fields)) {
185 | throw new \Exception('Table fields can\'t be empty');
186 | }
187 | foreach ($fields as $field) {
188 | $rows[] = "\$grid->{$field['name']}('{$field['name']}');\n";
189 | }
190 |
191 | $this->DummyGridField = trim(implode(str_repeat(' ', 8), $rows), "\n");
192 |
193 | return $this;
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/src/Scaffold/MigrationCreator.php:
--------------------------------------------------------------------------------
1 | ensureMigrationDoesntAlreadyExist($name);
34 |
35 | $path = $this->getPath($name, $path);
36 |
37 | $stub = $this->files->get(__DIR__.'/stubs/create.stub');
38 |
39 | $this->files->put($path, $this->populateStub($name, $stub, $table));
40 |
41 | $this->firePostCreateHooks($table);
42 |
43 | return $path;
44 | }
45 |
46 | /**
47 | * Populate stub.
48 | *
49 | * @param string $name
50 | * @param string $stub
51 | * @param string $table
52 | *
53 | * @return mixed
54 | */
55 | protected function populateStub($name, $stub, $table)
56 | {
57 | return str_replace(
58 | ['DummyClass', 'DummyTable', 'DummyStructure'],
59 | [$this->getClassName($name), $table, $this->bluePrint],
60 | $stub
61 | );
62 | }
63 |
64 | /**
65 | * Build the table blueprint.
66 | *
67 | * @param array $fields
68 | * @param string $keyName
69 | * @param bool|true $useTimestamps
70 | * @param bool|false $softDeletes
71 | *
72 | * @throws \Exception
73 | *
74 | * @return $this
75 | */
76 | public function buildBluePrint($fields = [], $keyName = 'id', $useTimestamps = true, $softDeletes = false)
77 | {
78 | $fields = array_filter($fields, function ($field) {
79 | return isset($field['name']) && !empty($field['name']);
80 | });
81 |
82 | if (empty($fields)) {
83 | throw new \Exception('Table fields can\'t be empty');
84 | }
85 |
86 | $rows[] = "\$table->increments('$keyName');\n";
87 |
88 | foreach ($fields as $field) {
89 | $column = "\$table->{$field['type']}('{$field['name']}')";
90 |
91 | if ($field['key']) {
92 | $column .= "->{$field['key']}()";
93 | }
94 |
95 | if (isset($field['default']) && $field['default']) {
96 | $column .= "->default('{$field['default']}')";
97 | }
98 |
99 | if (isset($field['comment']) && $field['comment']) {
100 | $column .= "->comment('{$field['comment']}')";
101 | }
102 |
103 | if (Arr::get($field, 'nullable') == 'on') {
104 | $column .= '->nullable()';
105 | }
106 |
107 | $rows[] = $column.";\n";
108 | }
109 |
110 | if ($useTimestamps) {
111 | $rows[] = "\$table->timestamps();\n";
112 | }
113 |
114 | if ($softDeletes) {
115 | $rows[] = "\$table->softDeletes();\n";
116 | }
117 |
118 | $this->bluePrint = trim(implode(str_repeat(' ', 12), $rows), "\n");
119 |
120 | return $this;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/Scaffold/ModelCreator.php:
--------------------------------------------------------------------------------
1 | tableName = $tableName;
40 |
41 | $this->name = $name;
42 |
43 | $this->files = $files ?: app('files');
44 | }
45 |
46 | /**
47 | * Create a new migration file.
48 | *
49 | * @param string $keyName
50 | * @param bool|true $timestamps
51 | * @param bool|false $softDeletes
52 | *
53 | * @throws \Exception
54 | *
55 | * @return string
56 | */
57 | public function create($keyName = 'id', $timestamps = true, $softDeletes = false)
58 | {
59 | $path = $this->getpath($this->name);
60 |
61 | if ($this->files->exists($path)) {
62 | throw new \Exception("Model [$this->name] already exists!");
63 | }
64 |
65 | $stub = $this->files->get($this->getStub());
66 |
67 | $stub = $this->replaceClass($stub, $this->name)
68 | ->replaceNamespace($stub, $this->name)
69 | ->replaceSoftDeletes($stub, $softDeletes)
70 | ->replaceTable($stub, $this->name)
71 | ->replaceTimestamp($stub, $timestamps)
72 | ->replacePrimaryKey($stub, $keyName)
73 | ->replaceSpace($stub);
74 |
75 | $this->files->put($path, $stub);
76 |
77 | return $path;
78 | }
79 |
80 | /**
81 | * Get path for migration file.
82 | *
83 | * @param string $name
84 | *
85 | * @return string
86 | */
87 | public function getPath($name)
88 | {
89 | $segments = explode('\\', $name);
90 |
91 | array_shift($segments);
92 |
93 | return app_path(implode('/', $segments)).'.php';
94 | }
95 |
96 | /**
97 | * Get namespace of giving class full name.
98 | *
99 | * @param string $name
100 | *
101 | * @return string
102 | */
103 | protected function getNamespace($name)
104 | {
105 | return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
106 | }
107 |
108 | /**
109 | * Replace class dummy.
110 | *
111 | * @param string $stub
112 | * @param string $name
113 | *
114 | * @return $this
115 | */
116 | protected function replaceClass(&$stub, $name)
117 | {
118 | $class = str_replace($this->getNamespace($name).'\\', '', $name);
119 |
120 | $stub = str_replace('DummyClass', $class, $stub);
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * Replace namespace dummy.
127 | *
128 | * @param string $stub
129 | * @param string $name
130 | *
131 | * @return $this
132 | */
133 | protected function replaceNamespace(&$stub, $name)
134 | {
135 | $stub = str_replace(
136 | 'DummyNamespace', $this->getNamespace($name), $stub
137 | );
138 |
139 | return $this;
140 | }
141 |
142 | /**
143 | * Replace soft-deletes dummy.
144 | *
145 | * @param string $stub
146 | * @param bool $softDeletes
147 | *
148 | * @return $this
149 | */
150 | protected function replaceSoftDeletes(&$stub, $softDeletes)
151 | {
152 | $import = $use = '';
153 |
154 | if ($softDeletes) {
155 | $import = "use Illuminate\\Database\\Eloquent\\SoftDeletes;\n";
156 | $use = "use SoftDeletes;\n";
157 | }
158 |
159 | $stub = str_replace(['DummyImportSoftDeletesTrait', 'DummyUseSoftDeletesTrait'], [$import, $use], $stub);
160 |
161 | return $this;
162 | }
163 |
164 | /**
165 | * Replace primarykey dummy.
166 | *
167 | * @param string $stub
168 | * @param string $keyName
169 | *
170 | * @return $this
171 | */
172 | protected function replacePrimaryKey(&$stub, $keyName)
173 | {
174 | $modelKey = $keyName == 'id' ? '' : "protected \$primaryKey = '$keyName';\n";
175 |
176 | $stub = str_replace('DummyModelKey', $modelKey, $stub);
177 |
178 | return $this;
179 | }
180 |
181 | /**
182 | * Replace Table name dummy.
183 | *
184 | * @param string $stub
185 | * @param string $name
186 | *
187 | * @return $this
188 | */
189 | protected function replaceTable(&$stub, $name)
190 | {
191 | $class = str_replace($this->getNamespace($name).'\\', '', $name);
192 |
193 | $table = Str::plural(strtolower($class)) !== $this->tableName ? "protected \$table = '$this->tableName';\n" : '';
194 |
195 | $stub = str_replace('DummyModelTable', $table, $stub);
196 |
197 | return $this;
198 | }
199 |
200 | /**
201 | * Replace timestamps dummy.
202 | *
203 | * @param string $stub
204 | * @param bool $timestamps
205 | *
206 | * @return $this
207 | */
208 | protected function replaceTimestamp(&$stub, $timestamps)
209 | {
210 | $useTimestamps = $timestamps ? '' : "public \$timestamps = false;\n";
211 |
212 | $stub = str_replace('DummyTimestamp', $useTimestamps, $stub);
213 |
214 | return $this;
215 | }
216 |
217 | /**
218 | * Replace spaces.
219 | *
220 | * @param string $stub
221 | *
222 | * @return mixed
223 | */
224 | public function replaceSpace($stub)
225 | {
226 | return str_replace(["\n\n\n", "\n \n"], ["\n\n", ''], $stub);
227 | }
228 |
229 | /**
230 | * Get stub path of model.
231 | *
232 | * @return string
233 | */
234 | public function getStub()
235 | {
236 | return __DIR__.'/stubs/model.stub';
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/src/Scaffold/stubs/controller.stub:
--------------------------------------------------------------------------------
1 | header(trans('admin.index'))
27 | ->description(trans('admin.description'))
28 | ->body($this->grid());
29 | }
30 |
31 | /**
32 | * Show interface.
33 | *
34 | * @param mixed $id
35 | * @param Content $content
36 | * @return Content
37 | */
38 | public function show($id, Content $content)
39 | {
40 | return $content
41 | ->header(trans('admin.detail'))
42 | ->description(trans('admin.description'))
43 | ->body($this->detail($id));
44 | }
45 |
46 | /**
47 | * Edit interface.
48 | *
49 | * @param mixed $id
50 | * @param Content $content
51 | * @return Content
52 | */
53 | public function edit($id, Content $content)
54 | {
55 | return $content
56 | ->header(trans('admin.edit'))
57 | ->description(trans('admin.description'))
58 | ->body($this->form()->edit($id));
59 | }
60 |
61 | /**
62 | * Create interface.
63 | *
64 | * @param Content $content
65 | * @return Content
66 | */
67 | public function create(Content $content)
68 | {
69 | return $content
70 | ->header(trans('admin.create'))
71 | ->description(trans('admin.description'))
72 | ->body($this->form());
73 | }
74 |
75 | /**
76 | * Make a grid builder.
77 | *
78 | * @return Grid
79 | */
80 | protected function grid()
81 | {
82 | $grid = new Grid(new DummyModel);
83 |
84 | $grid->id('ID');
85 | DummyGridField
86 | $grid->created_at(trans('admin.created_at'));
87 | $grid->updated_at(trans('admin.updated_at'));
88 |
89 | return $grid;
90 | }
91 |
92 | /**
93 | * Make a show builder.
94 | *
95 | * @param mixed $id
96 | * @return Show
97 | */
98 | protected function detail($id)
99 | {
100 | $show = new Show(DummyModel::findOrFail($id));
101 |
102 | $show->id('ID');
103 | DummyShowField
104 | $show->created_at(trans('admin.created_at'));
105 | $show->updated_at(trans('admin.updated_at'));
106 |
107 | return $show;
108 | }
109 |
110 | /**
111 | * Make a form builder.
112 | *
113 | * @return Form
114 | */
115 | protected function form()
116 | {
117 | $form = new Form(new DummyModel);
118 |
119 | $form->display('ID');
120 | DummyFormField
121 | $form->display(trans('admin.created_at'));
122 | $form->display(trans('admin.updated_at'));
123 |
124 | return $form;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Scaffold/stubs/create.stub:
--------------------------------------------------------------------------------
1 |