├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── composer.json
├── phpunit.xml
├── readme.md
├── resources
└── stubs
│ ├── component.stub
│ ├── component.view.stub
│ ├── console.stub
│ ├── contract.stub
│ ├── controller.plain.stub
│ ├── controller.stub
│ ├── controller_admin.stub
│ ├── controller_repository.stub
│ ├── event.stub
│ ├── example.stub
│ ├── exception.stub
│ ├── factory.stub
│ ├── job.stub
│ ├── listener.stub
│ ├── livewire.stub
│ ├── livewire.view.stub
│ ├── many_many_relationship.stub
│ ├── middleware.stub
│ ├── migration.plain.stub
│ ├── migration.stub
│ ├── model.plain.stub
│ ├── model.stub
│ ├── notification.stub
│ ├── pivot.stub
│ ├── repository.contract.stub
│ ├── repository.stub
│ ├── request.stub
│ ├── schema_change.stub
│ ├── schema_create.stub
│ ├── seeder.plain.stub
│ ├── seeder.stub
│ ├── test.stub
│ ├── trait.stub
│ ├── view.create_edit.b3.stub
│ ├── view.create_edit.stub
│ ├── view.index.b3.stub
│ ├── view.index.stub
│ ├── view.show.b3.stub
│ ├── view.show.stub
│ ├── view.stub
│ ├── view.test.stub
│ └── view.website.stub
├── src
├── Commands
│ ├── ComponentCommand.php
│ ├── ConsoleCommand.php
│ ├── ContractCommand.php
│ ├── ControllerCommand.php
│ ├── EventCommand.php
│ ├── EventGenerateCommand.php
│ ├── ExceptionCommand.php
│ ├── FactoryCommand.php
│ ├── FileCommand.php
│ ├── GeneratorCommand.php
│ ├── JobCommand.php
│ ├── ListenerCommand.php
│ ├── LivewireCommand.php
│ ├── MiddlewareCommand.php
│ ├── MigrationCommand.php
│ ├── MigrationPivotCommand.php
│ ├── ModelCommand.php
│ ├── NotificationCommand.php
│ ├── PublishCommand.php
│ ├── RepositoryCommand.php
│ ├── RequestCommand.php
│ ├── ResourceCommand.php
│ ├── SeederCommand.php
│ ├── TestCommand.php
│ ├── TraitCommand.php
│ └── ViewCommand.php
├── Exceptions
│ └── GeneratorException.php
├── GeneratorsServiceProvider.php
├── Migrations
│ ├── NameParser.php
│ ├── SchemaParser.php
│ └── SyntaxBuilder.php
├── Traits
│ ├── ArgumentsOptions.php
│ └── Settings.php
└── config
│ └── config.php
├── tests
├── ComponentCommandTest.php
├── ConsoleCommandTest.php
├── ContractCommandTest.php
├── ControllerCommandTest.php
├── EventCommandTest.php
├── ExceptionCommandTest.php
├── FactoryCommandTest.php
├── FileCommandTest.php
├── JobCommandTest.php
├── LivewireCommandTest.php
├── MiddlewareCommandTest.php
├── MigrationCommandTest.php
├── ModelCommandTest.php
├── NotificationCommandTest.php
├── RepositoryCommandTest.php
├── RequestCommandTest.php
├── ResourceCommandTest.php
├── SeederCommandTest.php
├── TestCase.php
├── TestCommandTest.php
├── TraitCommandTest.php
└── ViewCommandTest.php
└── todo.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: bpocallaghan
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | build
4 | vendor
5 | docs
6 | composer.lock
7 | .phpunit.result.cache
8 | tests/temp/database.sqlite
9 | app/
10 | tests/Unit
11 | tests/Feature
12 | tests/tests/Unit
13 | tests/tests/Feature
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Ben-Piet O'Callaghan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, 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,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bpocallaghan/generators",
3 | "description": "Custom Laravel File Generators with config and publishable stubs.",
4 | "keywords": [
5 | "laravel",
6 | "generators",
7 | "stubs",
8 | "config",
9 | "commands",
10 | "customization"
11 | ],
12 | "license": "MIT",
13 | "authors": [
14 | {
15 | "name": "Ben-Piet O'Callaghan",
16 | "email": "bpocallaghan@gmail.com",
17 | "homepage": "http://bpocallaghan.co.za",
18 | "role": "Developer"
19 | }
20 | ],
21 | "require": {
22 | "php": "^8.1",
23 | "symfony/console": "v7.0.4",
24 | "laravel/framework": "^11.0"
25 | },
26 | "require-dev": {
27 | "orchestra/testbench": "^7.1"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "Bpocallaghan\\Generators\\": "src"
32 | }
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "Bpocallaghan\\Generators\\Tests\\": "tests"
37 | }
38 | },
39 | "extra": {
40 | "laravel": {
41 | "providers": [
42 | "Bpocallaghan\\Generators\\GeneratorsServiceProvider"
43 | ]
44 | }
45 | },
46 | "scripts": {
47 | "test": "vendor/bin/phpunit"
48 | },
49 | "minimum-stability": "dev",
50 | "prefer-stable": true
51 | }
52 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 | tests/
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Laravel File Generators
2 |
3 | Custom Laravel File Generators with a config file and publishable stubs.
4 | You can publish the stubs. You can add your own stubs to generate.
5 |
6 | This package is being used in [Admin Starter Project](https://github.com/bpocallaghan/titan-starter) that focuses on test driven development and has the foundation ready for you.
7 |
8 | ```
9 | Laravel 5.1 : v2.1.3
10 | Laravel 5.2 - 5.3 : v3.0.3
11 | Laravel 5.4 : v4.1.9
12 | Laravel 5.5 - 5.8 : v5.0.0+
13 | Laravel 6.0 : v5.1.0+
14 | Laravel 7.0 : v6.x
15 | Laravel 8.0 : v7.x
16 | Laravel 9.0 : v8.x
17 | Laravel 10.0 : v9.x
18 | ```
19 |
20 | ## Commands
21 | ```bash
22 | php artisan generate:publish-stubs
23 | php artisan generate:model
24 | php artisan generate:view
25 | php artisan generate:controller
26 | php artisan generate:migration
27 | php artisan generate:migration:pivot
28 | php artisan generate:seed
29 | php artisan generate:resource
30 | php artisan generate:repository
31 | php artisan generate:contract
32 | php artisan generate:notification
33 | php artisan generate:event
34 | php artisan generate:listener
35 | php artisan generate:event-listener
36 | php artisan generate:trait
37 | php artisan generate:job
38 | php artisan generate:console
39 | php artisan generate:middleware
40 | php artisan generate:factory
41 | php artisan generate:test
42 | php artisan generate:file
43 | php artisan generate:exception
44 | php artisan generate:component
45 | php artisan generate:livewire
46 | ```
47 |
48 | ### Option for all the commands
49 | - `--force` This will override the existing file, if it exists.
50 | - `--test` This will also generate a test file.
51 |
52 | ### Option for all the commands, except `views` and `migration:pivot`
53 | - `--plain` This will use the .plain stub of the command (generate an empty controller)
54 |
55 | ### Customization
56 | This is for all except the `migration` and `migration:pivot` commands
57 |
58 | ```
59 | php artisan generate:file foo.bar --type=controller
60 | php artisan generate:view foo.bar --stub=view_show --name=baz_show
61 | php artisan generate:file foo.bar --type=controller --stub=controller_custom --name=BazzzController --plain --force
62 | ```
63 |
64 | You can specify a custom name of the file to be generated.
65 | You can add the --plain or --force options.
66 | You can override the default stub to be used.
67 | You can create your own stubs with the available placeholders.
68 | You can create new settings' types, for example:
69 | - 'exception' => ['namespace' => '\Exceptions', 'path' => './app/Exceptions/', 'postfix' => 'Exception'],
70 |
71 | [Available placeholders](https://github.com/bpocallaghan/generators/blob/master/resources/stubs/example.stub)
72 |
73 | ## Views Custom Stubs
74 |
75 | ```
76 | php artisan generate:view posts
77 | php artisan generate:view admin.posts --stub=custom
78 | php artisan generate:view admin.posts --stub=another_file
79 | ```
80 |
81 | ## Installation
82 |
83 | Update your project's `composer.json` file.
84 |
85 | ```
86 | composer require bpocallaghan/generators --dev
87 | ```
88 |
89 | Add the Service Provider (Laravel 5.5+ has automatic discovery of packages)
90 | You'll only want to use these generators for local development, add the provider in `app/Providers/AppServiceProvider.php`:
91 |
92 | ```php
93 | public function register()
94 | {
95 | if ($this->app->environment() == 'local') {
96 | $this->app->register(\Bpocallaghan\Generators\GeneratorsServiceProvider::class);
97 | }
98 | }
99 | ```
100 |
101 | Run `php artisan` command to see the new commands in the `generate:*` section
102 |
103 | ## Usage
104 |
105 | - [Models](#models)
106 | - [Views](#views)
107 | - [Controllers](#controllers)
108 | - [Migrations](#migrations)
109 | - [Pivot Tables](#pivot-tables)
110 | - [Database Seeders](#database-seeders)
111 | - [Resource](#resource)
112 | - [Repository](#repository)
113 | - [Contract](#contract)
114 | - [Notifications](#notifications)
115 | - [Events and Listeners](#events-and-listeners)
116 | - [Trait](#trait)
117 | - [Job](#job)
118 | - [Console](#console)
119 | - [Middleware](#middleware)
120 | - [Factory](#factory)
121 | - [Test](#test)
122 | - [File](#file)
123 | - [Configuration](#configuration)
124 |
125 | ### Models
126 |
127 | ```
128 | php artisan generate:model bar
129 | php artisan generate:model foo.bar --plain
130 | php artisan generate:model bar --force
131 | php artisan generate:model bar --factory
132 | php artisan generate:model bar --migration
133 | php artisan generate:model bar --migration --schema="title:string, body:text"
134 | ```
135 |
136 | ### Views
137 |
138 | ```
139 | php artisan generate:view foo
140 | php artisan generate:view foo.bar
141 | php artisan generate:view foo.bar --stub=view_show
142 | php artisan generate:view foo.bar --name=foo_bar
143 | ```
144 |
145 | ### Controllers
146 |
147 | ```
148 | php artisan generate:controller foo
149 | php artisan generate:controller foo.bar
150 | php artisan generate:controller fooBar
151 | php artisan generate:controller bar --plain
152 | php artisan generate:controller BarController --plain
153 | ```
154 |
155 | - The `Controller` postfix will be added if needed.
156 |
157 |
158 | ### Migrations
159 |
160 | This is very similar as [Jeffrey Way's](https://github.com/laracasts/Laravel-5-Generators-Extended)
161 |
162 | ```
163 | php artisan generate:migration create_users_table
164 | php artisan generate:migration create_users_table --plain
165 | php artisan generate:migration create_users_table --force
166 | php artisan generate:migration create_posts_table --schema="title:string, body:text, slug:string:unique, published_at:date"
167 | ```
168 |
169 | ### Pivot Tables
170 |
171 | This is very similar as [Jeffrey Way's](https://github.com/laracasts/Laravel-5-Generators-Extended)
172 |
173 | ```
174 | php artisan generate:migration:pivot tags posts
175 | ```
176 |
177 | ### Database Seeders
178 |
179 | ```
180 | php artisan generate:seed bar
181 | php artisan generate:seed BarTableSeeder
182 | ```
183 |
184 | - The `TableSeeder` suffix will be added if needed.
185 |
186 | ### Resource
187 |
188 | ```
189 | php artisan generate:resource bar
190 | php artisan generate:resource foo.bar
191 | php artisan generate:resource foo.bar_baz
192 | php artisan generate:resource bar --schema="title:string, body:text, slug:string:unique, published_at:date"
193 | php artisan generate:resource articles --controller=admin
194 | ```
195 |
196 | - This will generate a Bar model, BarsController, resources views (in config), create_bars_table migration, BarTableSeeder
197 | - In the config there is a `resource_views` array, you can specify the views that you want to generate there, just make sure the stub exist.
198 | - This will also ask you to generate the 'repository - contract pattern' files.
199 | - The `--controller=admin` allows you to use the controller_admin stub when generating the controller.
200 |
201 | ### Repository
202 | ```
203 | php artisan generate:repository Posts
204 | ```
205 | This will generate a Posts Repository file to be used in your controller.
206 |
207 | ### Contract
208 | ```
209 | php artisan generate:contract Cache
210 | ```
211 | This will generate a Cache Contract file to be used with your repositories.
212 |
213 | ### Notifications
214 |
215 | ```
216 | php artisan generate:notification UserRegistered
217 | ```
218 |
219 | This will generate a UserRegistered notification.
220 | Laravel provides support for sending notifications across a variety of delivery channels, including mail, SMS (via Nexmo), and Slack. Notifications may also be stored in a database so they may be displayed in your web interface.
221 |
222 | ### Events and Listeners
223 |
224 | ```
225 | php artisan generate:event InvoiceWasPaid
226 | php artisan generate:listener NotifyUserAboutPayment --event=InvoiceWasPaid
227 | php artisan generate:event-listener
228 | ```
229 | This will generate the event and listener.
230 | Laravel's events provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application
231 |
232 | `php artisan generate:event-listener `
233 | Will generate all the missing events and listeners defined in your EventServiceProvider.
234 |
235 | ### Trait
236 | ```
237 | php artisan generate:trait Http\Controllers\Traits\Bar
238 | ```
239 | This will generate a FooBar Trait file. The command will use the name as your namespace.
240 | `generate:trait Foo` will create a file in `app/Foo.php`, `generate:trait Foo\Bar` will create a file in `app/Foo/Bar.php`.
241 |
242 | ### Job
243 | ```
244 | php artisan generate:job SendReminderEmail
245 | ```
246 | This will generate a SendReminderEmail Job file.
247 |
248 | ### Console (Artisan Command)
249 | ```
250 | php artisan generate:console SendEmails
251 | php artisan generate:console SendEmails --command=send:emails
252 | ```
253 | This will generate a SendEmails Artisan Command file. The --command option is optional.
254 |
255 | ### Middleware
256 | ```
257 | php artisan generate:middleware AuthenticateAdmin
258 | ```
259 | This will generate an AuthenticateAdmin Middleware file.
260 |
261 | ### Factory
262 | ```
263 | php artisan generate:factory Post
264 | php artisan generate:factory PostFactory
265 | ```
266 | This will generate a PostFactory model file.
267 |
268 | ### Test
269 | ```
270 | php artisan generate:test UserCanLogin
271 | php artisan generate:test Post --unit
272 | php artisan generate:test Auth\LoginTest
273 | ```
274 | This will generate Feature\UserCanLogin and Unit\PostTest and Unit\Auth\LoginTest files.
275 |
276 | ### Component
277 | ```
278 | php artisan generate:component Foo
279 | php artisan generate:component Foo/Bar
280 | php artisan generate:component Baz --test
281 | ```
282 | This will generate a Laravel Component. The php and blade files will be generated.
283 | You can also specify to generate a unit test.
284 |
285 | ### Livewire
286 | ```
287 | php artisan generate:livewire Foo
288 | php artisan generate:livewire Foo/Bar
289 | php artisan generate:livewire Baz --test
290 | php artisan generate:livewire foo-bar --request
291 | ```
292 | This will generate a Livewire component. The php and blade files will be generated.
293 | You can also specify to generate a test or a form request.
294 |
295 | ### Configuration
296 |
297 | ```
298 | php artisan generate:publish-stubs
299 | ```
300 |
301 | This will copy the config file to `/config/generators.php`.
302 | Here you can change the defaults for the settings of each `type`, like model, view, controller, seed.
303 | You can also change the namespace, path where to create the file, the pre/post fix, and more.
304 | You can also add new stubs.
305 |
306 | This will also copy all the stubs to `/resources/stubs/`.
307 | Here you can make changes to the current stubs, add your own boilerplate / comments to the files.
308 | You can also add your own stubs here and specify it in the config to be used.
309 | **Migration Stub Note**: The `migration.stub` is only the outer part and the `schema_create.stub or schema_change.stub` is where you modify the schema itself. The `schema_create.stub` has boilerplate added to it.
310 |
311 | ### File
312 |
313 | This is the base command for the view, model, controller, seed commands.
314 | The migration and migration:pivot uses Jeffrey's classes.
315 | In the config there is a `settings` array, this is the 'types' and their settings. You can add more, for example, if you use repositories, you can add it here.
316 |
317 | ```
318 | php artisan generate:file foo.bar --type=view
319 | php artisan generate:file foo.bar --type=controller
320 | php artisan generate:file foo.bar --type=model
321 | php artisan generate:file foo.bar --type=model --stub=model_custom
322 | ```
323 |
324 | ## Customizing file was created message to add support for ide opening the files
325 |
326 | Make links for opening output.
327 | Add output_path_handler as a function to your config/generators.php.Example:
328 |
329 | ```
330 | 'output_path_handler' => static function($path){
331 | return 'file:///' . base_path() . $path;
332 | },
333 | ```
334 | This will output a file schema uri which JetBrain Products (Intellij,Php Storm,Web Storm,...) then can open directly from your terminal.
335 |
336 | ## Thank you
337 |
338 | - Thank you, [Taylor Ottwell](https://github.com/taylorotwell) for [Laravel](http://laravel.com/).
339 | - Thank you, [Jeffrey Way](https://github.com/JeffreyWay) for the awesome resources at [Laracasts](https://laracasts.com/).
340 |
341 | ## My Other Packages
342 |
343 | - [Alert](https://github.com/bpocallaghan/alert) A helper package to flash a bootstrap alert to the browser via a Facade or a helper function.
344 | - [Notify](https://github.com/bpocallaghan/notify) Laravel Flash Notifications with icons and animations and with a timeout
345 | - [Impersonate User](https://github.com/bpocallaghan/impersonate) This allows you to authenticate as any of your customers.
346 | - [Sluggable](https://github.com/bpocallaghan/sluggable) Provides a HasSlug trait that will generate a unique slug when saving your Laravel Eloquent model.
347 |
--------------------------------------------------------------------------------
/resources/stubs/component.stub:
--------------------------------------------------------------------------------
1 |
2 | {{-- Any code of your own that you haven’t looked at for six or more months might as well have been written by someone else. --}}
3 | {{-- If you have to spend effort looking at a fragment of code and figuring out what it’s doing, then you should extract it into a function and name the function after the what. --}}
4 |
5 |
--------------------------------------------------------------------------------
/resources/stubs/console.stub:
--------------------------------------------------------------------------------
1 | view('index');
14 | }
15 | }
--------------------------------------------------------------------------------
/resources/stubs/controller.stub:
--------------------------------------------------------------------------------
1 | view('{{viewPath}}.index', [
24 | 'items' => {{model}}::all()
25 | ]);
26 | }
27 |
28 | /**
29 | * Show the form for creating a new {{resource}}.
30 | *
31 | * @return Factory|View
32 | */
33 | public function create()
34 | {
35 | return $this->view('{{viewPath}}.create_edit');
36 | }
37 |
38 | /**
39 | * Store a newly created {{resource}} in storage.
40 | *
41 | * @return RedirectResponse|Redirector
42 | */
43 | public function store({{model}}Request $request)
44 | {
45 | ${{resource}} = $this->createEntry({{model}}::class, $request->validated());
46 |
47 | return redirect_to_resource();
48 | }
49 |
50 | /**
51 | * Display the specified {{resource}}.
52 | *
53 | * @param {{model}} ${{resource}}
54 | * @return Factory|View
55 | */
56 | public function show({{model}} ${{resource}})
57 | {
58 | return $this->view('{{viewPath}}.show')->with('item', ${{resource}});
59 | }
60 |
61 | /**
62 | * Show the form for editing the specified {{resource}}.
63 | *
64 | * @param {{model}} ${{resource}}
65 | * @return Factory|View
66 | */
67 | public function edit({{model}} ${{resource}})
68 | {
69 | return $this->view('{{viewPath}}.create_edit')->with('item', ${{resource}});
70 | }
71 |
72 | /**
73 | * Update the specified {{resource}} in storage.
74 | *
75 | * @param {{model}} ${{resource}}
76 | * @return RedirectResponse|Redirector
77 | */
78 | public function update({{model}}Request $request, {{model}} ${{resource}})
79 | {
80 | ${{resource}} = $this->updateEntry(${{resource}}, $request->validated());
81 |
82 | return redirect_to_resource();
83 | }
84 |
85 | /**
86 | * Remove the specified {{resource}} from storage.
87 | *
88 | * @param {{model}} ${{resource}}
89 | * @return RedirectResponse|Redirector
90 | */
91 | public function destroy({{model}} ${{resource}})
92 | {
93 | $this->deleteEntry(${{resource}}, request());
94 |
95 | return redirect_to_resource();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/resources/stubs/controller_repository.stub:
--------------------------------------------------------------------------------
1 | {{resourceLowercase}} = ${{resourceLowercase}};
28 | }
29 |
30 | /**
31 | * Display a listing of {{resource}}.
32 | *
33 | * @return Response
34 | */
35 | public function index()
36 | {
37 | save_resource_url();
38 |
39 | return $this->view('{{viewPath}}.index')->with('items', {{model}}::all());
40 | }
41 |
42 | /**
43 | * Show the form for creating a new {{resource}}.
44 | *
45 | * @return Response
46 | */
47 | public function create()
48 | {
49 | return $this->view('{{viewPath}}.create_edit');
50 | }
51 |
52 | /**
53 | * Store a newly created {{resource}} in storage.
54 | *
55 | * @param Request $request
56 | * @return Response
57 | */
58 | public function store(Request $request)
59 | {
60 | $this->validate($request, {{model}}::$rules, {{model}}::$messages);
61 |
62 | $this->createEntry({{model}}::class, $request->all());
63 |
64 | return redirect_to_resource();
65 | }
66 |
67 | /**
68 | * Display the specified {{resource}}.
69 | *
70 | * @param {{model}} ${{resource}}
71 | * @return Response
72 | */
73 | public function show({{model}} ${{resource}})
74 | {
75 | return $this->view('{{viewPath}}.show')->with('item', ${{resource}});
76 | }
77 |
78 | /**
79 | * Show the form for editing the specified {{resource}}.
80 | *
81 | * @param {{model}} ${{resource}}
82 | * @return Response
83 | */
84 | public function edit({{model}} ${{resource}})
85 | {
86 | return $this->view('{{viewPath}}.create_edit')->with('item', ${{resource}});
87 | }
88 |
89 | /**
90 | * Update the specified {{resource}} in storage.
91 | *
92 | * @param {{model}} ${{resource}}
93 | * @param Request $request
94 | * @return Response
95 | */
96 | public function update({{model}} ${{resource}}, Request $request)
97 | {
98 | $this->validate($request, {{model}}::$rules, {{model}}::$messages);
99 |
100 | $this->updateEntry(${{resource}}, $request->all());
101 |
102 | return redirect_to_resource();
103 | }
104 |
105 | /**
106 | * Remove the specified {{resource}} from storage.
107 | *
108 | * @param {{model}} ${{resource}}
109 | * @param Request $request
110 | * @return Response
111 | */
112 | public function destroy({{model}} ${{resource}}, Request $request)
113 | {
114 | $this->deleteEntry(${{resource}}, $request);
115 |
116 | return redirect_to_resource();
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/resources/stubs/event.stub:
--------------------------------------------------------------------------------
1 | resource = new {{model}};
19 | $this->resource->name = '';
20 | }
21 |
22 | public function rules(): array
23 | {
24 | return (new {{class}}Request())->rules();
25 | }
26 |
27 | public function submit()
28 | {
29 | $this->validate();
30 |
31 | $this->resource->save();
32 |
33 | $this->resetForm();
34 |
35 | alert()->success("", "Entry saved.");
36 | }
37 |
38 | public function render()
39 | {
40 | return view('livewire.{{view}}');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/resources/stubs/livewire.view.stub:
--------------------------------------------------------------------------------
1 |
2 | {{-- If you don't make mistakes, you're not working on hard enough problems. --}}
3 | {{-- Any fool can write code that a computer can understand. Good programmers write code that humans can understand. --}}
4 |
5 |
--------------------------------------------------------------------------------
/resources/stubs/many_many_relationship.stub:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Get the {{model}} many to many
4 | */
5 | public function {{relationship}}()
6 | {
7 | return $this->belongsToMany({{model}}::class);
8 | }
9 |
--------------------------------------------------------------------------------
/resources/stubs/middleware.stub:
--------------------------------------------------------------------------------
1 | line('The introduction to the notification.')
43 | ->action('Notification Action', url('/'))
44 | ->line('Thank you for using our application!');
45 | }
46 |
47 | /**
48 | * Get the array representation of the notification.
49 | *
50 | * @param mixed $notifiable
51 | * @return array
52 | */
53 | public function toArray($notifiable)
54 | {
55 | return [
56 | //
57 | ];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/resources/stubs/pivot.stub:
--------------------------------------------------------------------------------
1 | integer('{{columnOne}}_id')->unsigned()->index();
17 | $table->foreign('{{columnOne}}_id')->references('id')->on('{{tableOne}}')->onDelete('cascade');
18 | $table->integer('{{columnTwo}}_id')->unsigned()->index();
19 | $table->foreign('{{columnTwo}}_id')->references('id')->on('{{tableTwo}}')->onDelete('cascade');
20 | $table->primary(['{{columnOne}}_id', '{{columnTwo}}_id']);
21 | });
22 | }
23 |
24 | /**
25 | * Reverse the migrations.
26 | *
27 | * @return void
28 | */
29 | public function down()
30 | {
31 | Schema::drop('{{pivotTableName}}');
32 | }
33 | }
--------------------------------------------------------------------------------
/resources/stubs/repository.contract.stub:
--------------------------------------------------------------------------------
1 | {{resourceLowercase}} = ${{resourceLowercase}};
25 | }
26 |
27 | public function all()
28 | {
29 | return $this->{{resourceLowercase}}->all();
30 | }
31 |
32 | /**
33 | * @param Request $request
34 | * @return mixed
35 | */
36 | public function getColumn(Request $request)
37 | {
38 | // TODO: Implement getColumn() method.
39 | }
40 |
41 | /**
42 | * @param Request $request
43 | * @return mixed
44 | */
45 | public function getList(Request $request)
46 | {
47 | // TODO: Implement getList() method.
48 | }
49 |
50 | /**
51 | * @param Request $request
52 | * @return mixed
53 | */
54 | public function create(Request $request)
55 | {
56 | // TODO: Implement create() method.
57 | }
58 |
59 | /**
60 | * @param Request $request
61 | * @param $id
62 | * @return mixed
63 | */
64 | public function update(Request $request, $id)
65 | {
66 | // TODO: Implement update() method.
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/resources/stubs/repository.stub:
--------------------------------------------------------------------------------
1 | check();
17 | }
18 |
19 | /**
20 | * Get the validation rules that apply to the request.
21 | *
22 | * @return array
23 | */
24 | public function rules()
25 | {
26 | return [
27 | //'name' => 'required|min:3|max:245',
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/stubs/schema_change.stub:
--------------------------------------------------------------------------------
1 | Schema::table('{{table}}', function(Blueprint $table) {
2 | {{schema_up}}
3 | });
--------------------------------------------------------------------------------
/resources/stubs/schema_create.stub:
--------------------------------------------------------------------------------
1 | Schema::create('{{table}}', function (Blueprint $table) {
2 | $table->bigIncrements('id')->unique()->index();
3 | {{schema_up}}
4 | $table->timestamps();
5 | $table->softDeletes();
6 | $table->integer('created_by')->unsigned();
7 | $table->integer('updated_by')->unsigned()->nullable();
8 | $table->integer('deleted_by')->unsigned()->nullable();
9 | });
--------------------------------------------------------------------------------
/resources/stubs/seeder.plain.stub:
--------------------------------------------------------------------------------
1 | $item)
21 | {
22 | {{model}}::create([
23 |
24 | ]);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/resources/stubs/test.stub:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
13 |
14 |
15 |
16 | @include('titan::admin.partials.info')
17 |
18 |
107 |
108 |
109 |
110 |
111 | @endsection
112 |
113 | @section('scripts')
114 | @parent
115 |
122 | @endsection
123 |
--------------------------------------------------------------------------------
/resources/stubs/view.create_edit.stub:
--------------------------------------------------------------------------------
1 | @extends('admin.admin')
2 |
3 | @section('content')
4 |
5 |
17 |
18 |
id}" : '')}}" accept-charset="UTF-8" enctype="multipart/form-data">
19 |
20 |
21 |
22 |
23 | @include('admin.partials.info')
24 |
25 |
26 |
27 |
28 |
29 | Name
30 |
31 | {!! form_error_message('name', $errors) !!}
32 |
33 |
34 |
35 |
36 |
59 |
60 |
61 |
62 |
73 | @if(isset($item) && $item && $item->image)
74 |
75 |
76 |
77 |
78 | @endif
79 |
80 |
81 |
99 |
100 |
101 |
102 | Content
103 | {{ ($errors && $errors->any()? old('content') : (isset($item)? $item->content : '')) }}
104 | {!! form_error_message('content', $errors) !!}
105 |
106 |
107 |
108 |
111 |
112 |
113 | @endsection
114 |
115 | @section('scripts')
116 | @parent
117 |
124 | @endsection
125 |
--------------------------------------------------------------------------------
/resources/stubs/view.index.b3.stub:
--------------------------------------------------------------------------------
1 | @extends('titan::layouts.admin')
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 | @include('titan::admin.partials.info')
17 |
18 | @include('titan::admin.partials.toolbar')
19 |
20 |
21 |
22 |
23 | {{model}}
24 | Description
25 | Created
26 | Action
27 |
28 |
29 |
30 | @foreach ($items as $item)
31 |
32 | {{ $item->name }}
33 | {!! $item->content !!}
34 | {{ $item->created_at->format('d M Y') }}
35 | {!! action_row($selectedNavigation->url, $item->id, $item->name, ['show', 'edit', 'delete']) !!}
36 |
37 | @endforeach
38 |
39 |
40 |
41 |
42 |
43 |
44 | @endsection
45 |
--------------------------------------------------------------------------------
/resources/stubs/view.index.stub:
--------------------------------------------------------------------------------
1 | @extends('admin.admin')
2 |
3 | @section('content')
4 |
5 |
14 |
15 |
16 | @include('admin.partials.info')
17 |
18 | @include('admin.partials.card.buttons')
19 |
20 |
21 |
22 |
23 | {{model}}
24 | Description
25 | Created
26 | Action
27 |
28 |
29 |
30 | @foreach ($items as $item)
31 |
32 | {{ $item->name }}
33 | {!! $item->content !!}
34 | {{ $item->created_at->format('d M Y') }}
35 | {!! action_row($selectedNavigation->url, $item->id, $item->name, ['show', 'edit', 'delete']) !!}
36 |
37 | @endforeach
38 |
39 |
40 |
41 |
42 | @endsection
43 |
--------------------------------------------------------------------------------
/resources/stubs/view.show.b3.stub:
--------------------------------------------------------------------------------
1 | @extends('titan::layouts.admin')
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 | @include('titan::admin.partials.info')
17 |
18 |
19 |
20 |
21 |
22 |
23 | {{model}}
24 |
25 |
26 |
27 |
28 |
29 |
30 | Slug
31 |
32 |
33 |
34 |
35 |
41 |
42 |
43 |
44 | @include('titan::admin.partials.form_footer', ['submit' => false])
45 |
46 |
47 |
48 |
49 |
50 | @endsection
51 |
--------------------------------------------------------------------------------
/resources/stubs/view.show.stub:
--------------------------------------------------------------------------------
1 |
2 | @extends('admin.admin')
3 |
4 | @section('content')
5 |
6 |
15 |
16 |
17 | @include('admin.partials.info')
18 |
19 |
20 |
21 |
22 |
23 |
24 | {{model}}
25 |
26 |
27 |
28 |
29 |
30 |
31 | Slug
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
49 |
50 | @endsection
51 |
--------------------------------------------------------------------------------
/resources/stubs/view.stub:
--------------------------------------------------------------------------------
1 | {{path}}
--------------------------------------------------------------------------------
/resources/stubs/view.test.stub:
--------------------------------------------------------------------------------
1 | view('{{view}}.index')->with('items', {{model}}::all());
18 | }
19 |
20 | /**
21 | * Show the form for creating a new {{resource}}.
22 | *
23 | * @return Response
24 | */
25 | public function create()
26 | {
27 | return $this->view('{{view}}.add_edit');
28 | }
29 |
30 | public function store(Request $request)
31 | {
32 | $this->validate($request, {{model}}::$rules, {{model}}::$messages);
33 |
34 | ${{resource}} = $this->createEntry('App\Models\{{model}}', $request->all());
35 |
36 | return Redirect::route('{{view}}.index');
37 | }
38 |
39 | /**
40 | * Display the specified {{resource}}.
41 | *
42 | * @param {{model}} ${{resource}}
43 | * @return Response
44 | */
45 | public function show({{model}} ${{resource}})
46 | {
47 | return $this->view('{{view}}.show')->with('item', ${{resource}});
48 | }
49 | }
--------------------------------------------------------------------------------
/resources/stubs/view.website.stub:
--------------------------------------------------------------------------------
1 | @extends('layouts.website')
2 |
3 | @section('content')
4 |
5 |
6 | @include('website.pages.page_header')
7 |
8 |
11 |
12 |
13 |
14 | @include('website.pages.page_side')
15 |
16 |
17 | @endsection
18 |
19 | @section('scripts')
20 | @parent
21 |
26 | @endsection
--------------------------------------------------------------------------------
/src/Commands/ComponentCommand.php:
--------------------------------------------------------------------------------
1 | call('generate:file', [
34 | 'name' => $this->argumentName(),
35 | '--type' => strtolower($this->type) . '_view',
36 | '--stub' => strtolower($this->type) . '_view',
37 | ]);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Commands/ConsoleCommand.php:
--------------------------------------------------------------------------------
1 | laravel->getProvider(EventServiceProvider::class);
36 |
37 | foreach ($provider->listens() as $event => $listeners) {
38 | $this->makeEventAndListeners($event, $listeners);
39 | }
40 |
41 | $this->info('Events and listeners generated successfully!');
42 | }
43 |
44 | /**
45 | * Make the event and listeners for the given event.
46 | *
47 | * @param string $event
48 | * @param array $listeners
49 | * @return void
50 | */
51 | protected function makeEventAndListeners($event, $listeners)
52 | {
53 | if (! Str::contains($event, '\\')) {
54 | return;
55 | }
56 |
57 | $this->call('generate:event', ['name' => $event]);
58 |
59 | $this->makeListeners($event, $listeners);
60 | }
61 |
62 | /**
63 | * Make the listeners for the given event.
64 | *
65 | * @param string $event
66 | * @param array $listeners
67 | * @return void
68 | */
69 | protected function makeListeners($event, $listeners)
70 | {
71 | foreach ($listeners as $listener) {
72 | $listener = preg_replace('/@.+$/', '', $listener);
73 |
74 | $this->call('generate:listener', ['name' => $listener, '--event' => $event]);
75 | }
76 | }
77 |
78 | /**
79 | * Get the console command arguments.
80 | *
81 | * @return array
82 | */
83 | protected function getArguments()
84 | {
85 | return [];
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Commands/ExceptionCommand.php:
--------------------------------------------------------------------------------
1 | getArgumentNameOnly();
36 |
37 | switch ($this->option('type')) {
38 | case 'view':
39 | break;
40 | case 'model':
41 | $name = $this->getModelName();
42 | break;
43 | case 'controller':
44 | case 'livewire':
45 | case 'component':
46 | $name = $this->getControllerName($name);
47 | break;
48 | case 'livewire_view':
49 | case 'component_view':
50 | $name = $this->getViewName($name);
51 | break;
52 | case 'seeder':
53 | $name = $this->getSeederName($name);
54 | break;
55 | }
56 |
57 | // override the name
58 | if ($this->option('name')) {
59 | return $this->option('name') . $this->settings['file_type'];
60 | }
61 |
62 | return $this->settings['prefix'] . $name . $this->settings['postfix'] . $this->settings['file_type'];
63 | }
64 |
65 | /**
66 | * Execute the console command.
67 | * @return void
68 | * @throws FileNotFoundException
69 | */
70 | public function handle()
71 | {
72 | $this->setSettings();
73 | $this->getResourceName($this->getUrl(false));
74 |
75 | // check the path where to create and save file
76 | $path = $this->getPath('');
77 | if ($this->files->exists($path) && $this->optionForce() === false) {
78 | return $this->error($this->type . ' already exists!');
79 | }
80 |
81 | // make all the directories
82 | $this->makeDirectory($path);
83 |
84 | // build file and save it at location
85 | $this->files->put($path, $this->buildClass($this->argumentName()));
86 |
87 | // check if there is an output handler function
88 | $output_handler = config('generators.output_path_handler');
89 | $this->info(ucfirst($this->option('type')) . ' created successfully.');
90 | if (is_callable($output_handler)) {
91 | // output to console from the user defined function
92 | $this->info($output_handler(Str::after($path, '.')));
93 | } else {
94 | // output to console
95 | $this->info('- ' . $path);
96 | }
97 |
98 | // if we need to run "composer dump-autoload"
99 | if ($this->settings['dump_autoload'] === true) {
100 | if ($this->confirm("Run 'composer dump-autoload'?")) {
101 | $this->composer->dumpAutoloads();
102 | }
103 | }
104 |
105 | // if we need to generate a test file
106 | if ($this->option('test')) {
107 | // ./app/Http
108 | $name = Str::replace('./app', '', $path);
109 | $name = Str::replace('/Http/', '', $name);
110 | $name = Str::replace('.php', '', $name);
111 |
112 | $this->call('generate:test', [
113 | 'name' => $name,
114 | '--unit' => !(Str::contains($this->settings['namespace'], 'Http\\')),
115 | ]);
116 | }
117 | }
118 |
119 | /**
120 | * Get the destination class path.
121 | *
122 | * @param string $name
123 | * @return string
124 | */
125 | protected function getPath($name)
126 | {
127 | $name = $this->getFileName();
128 |
129 | $withName = (bool)$this->option('name');
130 |
131 | $path = $this->settings['path'];
132 |
133 | if ($this->settingsDirectoryNamespace() === true) {
134 | $path .= $this->getArgumentPath($withName);
135 | }
136 |
137 | $path .= $name;
138 |
139 | return $path;
140 | }
141 |
142 | /**
143 | * Build the class with the given name.
144 | *
145 | * @param string $name
146 | * @return string
147 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
148 | */
149 | protected function buildClass($name)
150 | {
151 | $stub = $this->files->get($this->getStub());
152 |
153 | // examples used for the placeholders is for 'foo.bar'
154 |
155 | // App\Foo
156 | $stub = str_replace('{{namespace}}', $this->getNamespace($name), $stub);
157 |
158 | // Foo
159 | $stub = str_replace('{{namespaceWithoutApp}}', $this->getNamespace($name, false), $stub);
160 |
161 | // App\
162 | $stub = str_replace('{{rootNamespace}}', $this->getLaravel()->getNamespace(), $stub);
163 |
164 | // Bar
165 | $stub = str_replace('{{class}}', $this->getClassName(), $stub);
166 |
167 | $url = $this->getUrl(); // /foo/bar
168 |
169 | // /foo/bar
170 | $stub = str_replace('{{url}}', $this->getUrl(), $stub);
171 |
172 | // bars
173 | $stub = str_replace('{{collection}}', $this->getCollectionName(), $stub);
174 |
175 | // Bars
176 | $stub = str_replace('{{collectionUpper}}', $this->getCollectionUpperName(), $stub);
177 |
178 | // Bar
179 | $stub = str_replace('{{model}}', $this->getModelName(), $stub);
180 |
181 | // Bar
182 | $stub = str_replace('{{resource}}', $this->resource, $stub);
183 |
184 | // bar
185 | $stub = str_replace('{{resourceLowercase}}', $this->resourceLowerCase, $stub);
186 |
187 | // ./resources/views/foo/bar.blade.php
188 | $stub = str_replace('{{path}}', $this->getPath(''), $stub);
189 |
190 | // foos.bars
191 | $stub = str_replace('{{view}}', $this->getViewPath($this->getUrl(false)), $stub);
192 |
193 | // foos.bars (remove admin or website if first word)
194 | $stub = str_replace('{{viewPath}}', $this->getViewPathFormatted($this->getUrl(false)), $stub);
195 |
196 | // bars
197 | $stub = str_replace('{{table}}', $this->getTableName($url), $stub);
198 |
199 | // console command name
200 | $stub = str_replace('{{command}}', $this->option('command'), $stub);
201 |
202 | // contract file name
203 | $stub = str_replace('{{contract}}', $this->getContractName(), $stub);
204 |
205 | // contract namespace
206 | $stub = str_replace('{{contractNamespace}}', $this->getContractNamespace(), $stub);
207 |
208 | return $stub;
209 | }
210 |
211 | /**
212 | * Get the full namespace name for a given class.
213 | *
214 | * @param string $name
215 | * @param bool $withApp
216 | * @return string
217 | */
218 | protected function getNamespace($name, $withApp = true)
219 | {
220 | $path = (strlen($this->settings['namespace']) >= 2 ? $this->settings['namespace'] . '\\' : '');
221 |
222 | // dont add the default namespace if specified not to in config
223 | if ($this->settingsDirectoryNamespace() === true) {
224 | $path .= str_replace('/', '\\', $this->getArgumentPath());
225 | }
226 |
227 | $pieces = array_map('ucfirst', explode('/', $path));
228 |
229 | $namespace = ($withApp === true ? $this->getLaravel()->getNamespace() : '') . implode('\\', $pieces);
230 |
231 | $namespace = rtrim(ltrim(str_replace('\\\\', '\\', $namespace), '\\'), '\\');
232 |
233 | return $namespace;
234 | }
235 |
236 | /**
237 | * Get the url for the given name
238 | *
239 | * @param bool $lowercase
240 | * @return string
241 | */
242 | protected function getUrl($lowercase = true)
243 | {
244 | if ($lowercase) {
245 | $url = '/' . rtrim(implode(
246 | '/',
247 | array_map('Str::snake', explode('/', $this->getArgumentPath(true)))
248 | ), '/');
249 | $url = (implode('/', array_map('Str::slug', explode('/', $url))));
250 |
251 | return $url;
252 | }
253 |
254 | return '/' . rtrim(implode('/', explode('/', $this->getArgumentPath(true))), '/');
255 | }
256 |
257 | /**
258 | * Get the class name
259 | * @return mixed
260 | */
261 | protected function getClassName()
262 | {
263 | return ucwords(Str::camel(str_replace(
264 | [$this->settings['file_type']],
265 | [''],
266 | $this->getFileName()
267 | )));
268 | }
269 |
270 | /**
271 | * Get the console command options.
272 | *
273 | * @return array
274 | */
275 | protected function getOptions()
276 | {
277 | return array_merge([
278 | ['type', null, InputOption::VALUE_OPTIONAL, 'The type of file: model, view, controller, migration, seed', 'view'],
279 | // optional for to generate:console
280 | ['command', null, InputOption::VALUE_OPTIONAL, 'The terminal command that should be assigned.', 'command:name'],
281 | // optional for to generate:test
282 | ['unit', null, InputOption::VALUE_OPTIONAL, 'Create a unit test.', 'Feature'],
283 | ], parent::getOptions());
284 | }
285 | }
286 |
--------------------------------------------------------------------------------
/src/Commands/GeneratorCommand.php:
--------------------------------------------------------------------------------
1 | composer = $composer;
47 | }
48 |
49 | /**
50 | * Execute the console command.
51 | *
52 | * @return void
53 | */
54 | public function handle()
55 | {
56 | $args = [
57 | 'name' => $this->argumentName(),
58 | '--type' => strtolower($this->type), // settings type
59 | '--plain' => $this->optionPlain(), // if plain stub
60 | '--force' => $this->optionForce(), // force override
61 | '--stub' => $this->optionStub(), // custom stub name
62 | '--name' => $this->optionName(), // custom name for file
63 | '--test' => $this->optionTest(), // also generate test file
64 | ];
65 |
66 | // extra custom option
67 | if ($this->extraOption) {
68 | $args["--{$this->extraOption}"] = $this->optionExtra();
69 | }
70 |
71 | $this->call('generate:file', $args);
72 | }
73 |
74 | /**
75 | * Only return the name of the file
76 | * Ignore the path / namespace of the file
77 | *
78 | * @return array|mixed|string
79 | */
80 | protected function getArgumentNameOnly()
81 | {
82 | $name = $this->argumentName();
83 |
84 | if (Str::contains($name, '/')) {
85 | $name = str_replace('/', '.', $name);
86 | }
87 |
88 | if (Str::contains($name, '\\')) {
89 | $name = str_replace('\\', '.', $name);
90 | }
91 |
92 | if (Str::contains($name, '.')) {
93 | return substr($name, strrpos($name, '.') + 1);
94 | }
95 |
96 | return $name;
97 | }
98 |
99 | /**
100 | * Return the path of the file
101 | *
102 | * @param bool $withName
103 | * @return array|mixed|string
104 | */
105 | protected function getArgumentPath($withName = false)
106 | {
107 | $name = $this->argumentName();
108 |
109 | if (Str::contains($name, '.')) {
110 | $name = str_replace('.', '/', $name);
111 | }
112 |
113 | if (Str::contains($name, '\\')) {
114 | $name = str_replace('\\', '/', $name);
115 | }
116 |
117 | // ucfirst char, for correct namespace
118 | $name = implode('/', array_map('ucfirst', explode('/', $name)));
119 |
120 | // if we need to keep lowercase
121 | if ($this->settingsDirectoryFormat() === 'strtolower') {
122 | $name = implode('/', array_map('strtolower', explode('/', $name)));
123 | }
124 |
125 | // if type Test -> see if Feature or Unit
126 | if ($this->option('type') === 'test') {
127 | $folder = $this->option('unit') ? 'Unit' : 'Feature'; // Feature unless null -> Unit
128 |
129 | $name = $folder . DIRECTORY_SEPARATOR . $name;
130 | }
131 |
132 | // if we want the path with name
133 | if ($withName) {
134 | return $name . '/';
135 | }
136 |
137 | if (Str::contains($name, '/')) {
138 | return substr($name, 0, strripos($name, '/') + 1);
139 | }
140 |
141 | // if test - return the prefix folder
142 | if ($this->option('type') === 'test') {
143 | return ($this->option('unit') ? 'Unit' : 'Feature') . DIRECTORY_SEPARATOR;
144 | }
145 |
146 | return '';
147 | }
148 |
149 | /**
150 | * Get the resource name
151 | *
152 | * @param $name
153 | * @param bool $format
154 | * @return string
155 | */
156 | protected function getResourceName($name, $format = true)
157 | {
158 | // we assume its already formatted to resource name
159 | if ($name && $format === false) {
160 | return $name;
161 | }
162 |
163 | $name = isset($name) ? $name : $this->resource;
164 |
165 | $this->resource = lcfirst(Str::singular(class_basename($name)));
166 | $this->resourceLowerCase = strtolower($name);
167 |
168 | return $this->resource;
169 | }
170 |
171 | /**
172 | * Get the name for the model
173 | *
174 | * @param null $name
175 | * @return string
176 | */
177 | protected function getModelName($name = null)
178 | {
179 | $name = isset($name) ? $name : $this->resource;
180 |
181 | //return ucwords(Str::camel($this->getResourceName($name)));
182 |
183 | return Str::singular(ucwords(Str::camel(class_basename($name))));
184 | }
185 |
186 | /**
187 | * Get the name for the controller
188 | *
189 | * @param null $name
190 | * @return string
191 | */
192 | protected function getControllerName($name = null)
193 | {
194 | return ucwords(Str::camel(str_replace($this->settings['postfix'], '', ($name))));
195 | }
196 |
197 | protected function getViewName(string $name = null): string
198 | {
199 | $name = strtolower(preg_replace('/([a-zA-Z])(?=[A-Z])/', '$1-', $name));
200 | return (str_replace($this->settings['postfix'], '', $name));
201 | }
202 |
203 | /**
204 | * Get the name for the seed
205 | *
206 | * @param null $name
207 | */
208 | protected function getSeederName($name = null): string
209 | {
210 | return ucwords(Str::camel(str_replace(
211 | $this->settings['postfix'],
212 | '',
213 | $this->getCollectionName($name)
214 | )));
215 | }
216 |
217 | /**
218 | * Get the name of the collection
219 | *
220 | * @param null $name
221 | * @return string
222 | */
223 | protected function getCollectionName($name = null)
224 | {
225 | return Str::plural($this->getResourceName($name));
226 | }
227 |
228 | /**
229 | * Get the plural uppercase name of the resource
230 | * @param null $name
231 | * @return null|string
232 | */
233 | protected function getCollectionUpperName($name = null)
234 | {
235 | $name = Str::plural($this->getResourceName($name));
236 |
237 | $pieces = explode('_', $name);
238 | $name = "";
239 | foreach ($pieces as $k => $str) {
240 | $name .= ucfirst($str);
241 | }
242 |
243 | return $name;
244 | }
245 |
246 | /**
247 | * Get the name of the contract
248 | * @param null $name
249 | * @return string
250 | */
251 | protected function getContractName($name = null)
252 | {
253 | $name = isset($name) ? $name : $this->resource;
254 |
255 | $name = Str::singular(ucwords(Str::camel(class_basename($name))));
256 |
257 | return $name . config('generators.settings.contract.postfix');
258 | }
259 |
260 | /**
261 | * Get the namespace of where contract was created
262 | * @param bool $withApp
263 | * @return string
264 | */
265 | protected function getContractNamespace($withApp = true)
266 | {
267 | // get path from settings
268 | $path = config('generators.settings.contract.namespace') . '\\';
269 |
270 | // dont add the default namespace if specified not to in config
271 | $path .= str_replace('/', '\\', $this->getArgumentPath());
272 |
273 | $pieces = array_map('ucfirst', explode('/', $path));
274 |
275 | $namespace = ($withApp === true ? $this->getLaravel()->getNamespace() : '') . implode('\\', $pieces);
276 |
277 | $namespace = rtrim(ltrim(str_replace('\\\\', '\\', $namespace), '\\'), '\\');
278 |
279 | return $namespace;
280 | }
281 |
282 | /**
283 | * Get the path to the view file
284 | *
285 | * @param $name
286 | * @return string
287 | */
288 | protected function getViewPath($name, $plural = false)
289 | {
290 | $pieces = explode('/', $name);
291 |
292 | // dont plural if reserve word
293 | foreach ($pieces as $k => $value) {
294 | if (!in_array($value, config('generators.reserve_words'))) {
295 | if (!$plural) {
296 | $pieces[$k] = Str::snake($pieces[$k], '-');
297 | } else {
298 | $pieces[$k] = Str::plural(Str::snake($pieces[$k], '-'));
299 | }
300 | }
301 | }
302 |
303 | $name = implode('.', $pieces);
304 |
305 | return strtolower(rtrim(ltrim($name, '.'), '.'));
306 | }
307 |
308 | /**
309 | * Remove 'admin' and 'webiste' if first in path
310 | * The Base Controller has it as a 'prefix path'
311 | *
312 | * @param $name
313 | * @return string
314 | */
315 | protected function getViewPathFormatted($name)
316 | {
317 | $path = $this->getViewPath($name);
318 |
319 | if (strpos($path, 'admin.') === 0) {
320 | $path = substr($path, 6);
321 | }
322 |
323 | if (strpos($path, 'admins.') === 0) {
324 | $path = substr($path, 7);
325 | }
326 |
327 | if (strpos($path, 'website.') === 0) {
328 | $path = substr($path, 8);
329 | }
330 |
331 | if (strpos($path, 'websites.') === 0) {
332 | $path = substr($path, 9);
333 | }
334 |
335 | return $path;
336 | }
337 |
338 | /**
339 | * Get the table name
340 | *
341 | * @param $name
342 | * @return string
343 | */
344 | protected function getTableName($name)
345 | {
346 | return str_replace("-", "_", Str::plural(Str::snake(class_basename($name))));
347 | }
348 |
349 | /**
350 | * Get name of file/class with the pre and post fix
351 | *
352 | * @param $name
353 | * @return string
354 | */
355 | protected function getFileNameComplete($name)
356 | {
357 | return $this->settings['prefix'] . $name . $this->settings['postfix'];
358 | }
359 |
360 | /**
361 | * Get the default namespace for the class.
362 | *
363 | * @param string $rootNamespace
364 | * @return string
365 | */
366 | protected function getDefaultNamespace($rootNamespace)
367 | {
368 | return $rootNamespace . config('generators.' . strtolower($this->type) . '_namespace');
369 | }
370 |
371 | /**
372 | * Get the stub file for the generator.
373 | *
374 | * @return string
375 | */
376 | protected function getStub()
377 | {
378 | $key = $this->getOptionStubKey();
379 | $stub = config('generators.stubs.' . $key);
380 | if ($stub === null) {
381 | if (app()->environment() === 'testing') {
382 | // Tests\TestCase.php
383 | dump('The stub does not exist in the config file - "' . $key . '"');
384 | }
385 | $this->error('The stub does not exist in the config file - "' . $key . '"');
386 | exit;
387 | }
388 |
389 | return $stub;
390 | }
391 |
392 | /**
393 | * Get the key where the stub is located
394 | *
395 | * @return string
396 | */
397 | protected function getOptionStubKey()
398 | {
399 | $plain = $this->option('plain');
400 | $stub = $this->option('stub') . ($plain ? '_plain' : '');
401 |
402 | // if no stub, we assume it's the same as the type
403 | if (is_null($this->option('stub'))) {
404 | $stub = $this->option('type') . ($plain ? '_plain' : '');
405 | }
406 |
407 | return $stub;
408 | }
409 |
410 | /**
411 | * Get the console command arguments.
412 | *
413 | * @return array
414 | */
415 | protected function getArguments()
416 | {
417 | return [
418 | ['name', InputArgument::REQUIRED, 'The name of class being generated.'],
419 | ];
420 | }
421 |
422 | /**
423 | * Get the console command options.
424 | *
425 | * @return array
426 | */
427 | protected function getOptions()
428 | {
429 | return [
430 | ['plain', null, InputOption::VALUE_NONE, 'Generate an empty class.'],
431 | ['force', null, InputOption::VALUE_NONE, 'Warning: Override file if it already exist'],
432 | ['stub', null, InputOption::VALUE_OPTIONAL, 'The name of the view stub you would like to generate.'],
433 | ['name', null, InputOption::VALUE_OPTIONAL, 'If you want to override the name of the file that will be generated.'],
434 | ['test', null, InputOption::VALUE_NONE, 'Generate a test file.'],
435 | ];
436 | }
437 | }
438 |
--------------------------------------------------------------------------------
/src/Commands/JobCommand.php:
--------------------------------------------------------------------------------
1 | option('event')) {
39 | return $this->error('Missing required option: --event=*NameOfEvent*');
40 | }
41 |
42 | // setup
43 | $this->setSettings();
44 | $this->getResourceName($this->getUrl(false));
45 |
46 | // check the path where to create and save file
47 | $path = $this->getPath('');
48 | if ($this->files->exists($path) && $this->optionForce() === false) {
49 | return $this->error($this->type . ' already exists!');
50 | }
51 |
52 | // make all the directories
53 | $this->makeDirectory($path);
54 |
55 | // build file and save it at location
56 | $this->files->put($path, $this->buildClass($this->argumentName()));
57 |
58 | // output to console
59 | // check if there is an output handler function
60 | $output_handler = config('generators.output_path_handler');
61 | $this->info(ucfirst($this->option('type')) . ' created successfully.');
62 | if (is_callable($output_handler)) {
63 | // output to console from the user defined function
64 | $this->info($output_handler(Str::after($path, '.')));
65 | } else {
66 | // output to console
67 | $this->info('- ' . $path);
68 | }
69 |
70 | // if we need to run "composer dump-autoload"
71 | if ($this->settings['dump_autoload'] === true) {
72 | $this->composer->dumpAutoloads();
73 | }
74 | }
75 |
76 | /**
77 | * Get the filename of the file to generate
78 | *
79 | * @return string
80 | */
81 | private function getFileName()
82 | {
83 | $name = $this->getArgumentNameOnly();
84 |
85 | switch ($this->option('type')) {
86 | case 'view':
87 |
88 | break;
89 | case 'model':
90 | $name = $this->getModelName();
91 | break;
92 | case 'controller':
93 | $name = $this->getControllerName($name);
94 | break;
95 | case 'seeder':
96 | $name = $this->getSeederName($name);
97 | break;
98 | }
99 |
100 | // override the name
101 | if ($this->option('name')) {
102 | return $this->option('name') . $this->settings['file_type'];
103 | }
104 |
105 | return $this->settings['prefix'] . $name . $this->settings['postfix'] . $this->settings['file_type'];
106 | }
107 |
108 | /**
109 | * Get the destination class path.
110 | *
111 | * @param string $name
112 | * @return string
113 | */
114 | protected function getPath($name)
115 | {
116 | $name = $this->getFileName();
117 |
118 | $withName = boolval($this->option('name'));
119 |
120 | $path = $this->settings['path'];
121 | if ($this->settingsDirectoryNamespace() === true) {
122 | $path .= $this->getArgumentPath($withName);
123 | }
124 |
125 | $path .= $name;
126 |
127 | return $path;
128 | }
129 |
130 | /**
131 | * Build the class with the given name.
132 | *
133 | * @param string $name
134 | * @return string
135 | */
136 | protected function buildClass($name)
137 | {
138 | $stub = $this->files->get($this->getStub());
139 |
140 | // examples used for the placeholders is for 'foo.bar'
141 |
142 | // App\Foo
143 | $stub = str_replace('{{namespace}}', $this->getNamespace($name), $stub);
144 |
145 | // App\
146 | $stub = str_replace('{{rootNamespace}}', $this->getLaravel()->getNamespace(), $stub);
147 |
148 | // Bar
149 | $stub = str_replace('{{class}}', $this->getClassName(), $stub);
150 |
151 | $url = $this->getUrl(); // /foo/bar
152 |
153 | // /foo/bar
154 | $stub = str_replace('{{url}}', $this->getUrl(), $stub);
155 |
156 | // bars
157 | $stub = str_replace('{{collection}}', $this->getCollectionName(), $stub);
158 |
159 | // Bars
160 | $stub = str_replace('{{collectionUpper}}', $this->getCollectionUpperName(), $stub);
161 |
162 | // Bar
163 | $stub = str_replace('{{model}}', $this->getModelName(), $stub);
164 |
165 | // Bar
166 | $stub = str_replace('{{resource}}', $this->resource, $stub);
167 |
168 | // bar
169 | $stub = str_replace('{{resourceLowercase}}', $this->resourceLowerCase, $stub);
170 |
171 | // ./resources/views/foo/bar.blade.php
172 | $stub = str_replace('{{path}}', $this->getPath(''), $stub);
173 |
174 | // foos.bars
175 | $stub = str_replace('{{view}}', $this->getViewPath($this->getUrl(false)), $stub);
176 |
177 | // bars
178 | $stub = str_replace('{{table}}', $this->getTableName($url), $stub);
179 |
180 | // event - listeners
181 | $event = $this->option('event');
182 |
183 | if (!Str::startsWith($event, $this->laravel->getNamespace()) && !Str::startsWith(
184 | $event,
185 | 'Illuminate'
186 | )
187 | ) {
188 | $event = $this->laravel->getNamespace() . 'Events\\' . $event;
189 | }
190 |
191 | // event class name
192 | $stub = str_replace('{{event}}', class_basename($event), $stub);
193 |
194 | // event with namespace
195 | $stub = str_replace('{{eventAndNamespace}}', $event, $stub);
196 |
197 | return $stub;
198 | }
199 |
200 | /**
201 | * Get the full namespace name for a given class.
202 | *
203 | * @param string $name
204 | * @param bool $withApp
205 | * @return string
206 | */
207 | protected function getNamespace($name, $withApp = true)
208 | {
209 | $path = (strlen($this->settings['namespace']) >= 2 ? $this->settings['namespace'] . '\\' : '');
210 |
211 | // dont add the default namespace if specified not to in config
212 | if ($this->settingsDirectoryNamespace() === true) {
213 | $path .= str_replace('/', '\\', $this->getArgumentPath());
214 | }
215 |
216 | $pieces = array_map('ucfirst', explode('/', $path));
217 |
218 | $namespace = ($withApp === true ? $this->getLaravel()->getNamespace() : '') . implode('\\', $pieces);
219 |
220 | $namespace = rtrim(ltrim(str_replace('\\\\', '\\', $namespace), '\\'), '\\');
221 |
222 | return $namespace;
223 | }
224 |
225 | /**
226 | * Get the url for the given name
227 | *
228 | * @param bool $lowercase
229 | * @return string
230 | */
231 | protected function getUrl($lowercase = true)
232 | {
233 | if ($lowercase) {
234 | $url = '/' . rtrim(implode(
235 | '/',
236 | array_map('Str::snake', explode('/', $this->getArgumentPath(true)))
237 | ), '/');
238 | $url = (implode('/', array_map('Str::slug', explode('/', $url))));
239 |
240 | return $url;
241 | }
242 |
243 | return '/' . rtrim(implode('/', explode('/', $this->getArgumentPath(true))), '/');
244 | }
245 |
246 | /**
247 | * Get the class name
248 | * @return mixed
249 | */
250 | protected function getClassName()
251 | {
252 | return ucwords(Str::camel(str_replace(
253 | [$this->settings['file_type']],
254 | [''],
255 | $this->getFileName()
256 | )));
257 | }
258 |
259 | /**
260 | * Get the console command options.
261 | *
262 | * @return array
263 | */
264 | protected function getOptions()
265 | {
266 | return array_merge([
267 | ['event', 'e', InputOption::VALUE_REQUIRED, 'The event class being listened for.'],
268 | ['type', null, InputOption::VALUE_OPTIONAL, 'Type is listener', 'listener']
269 | ], parent::getOptions());
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/src/Commands/LivewireCommand.php:
--------------------------------------------------------------------------------
1 | call('generate:file', [
36 | 'name' => $this->argumentName(),
37 | '--type' => strtolower($this->type) . '_view',
38 | '--stub' => strtolower($this->type) . '_view',
39 | ]);
40 |
41 | if ($this->option('request') === true || $this->option('request') === 'true') {
42 | $this->call('generate:request', [
43 | 'name' => $this->argumentName(),
44 | ]);
45 | }
46 | }
47 |
48 | /**
49 | * Get the console command options.
50 | * @return array
51 | */
52 | protected function getOptions()
53 | {
54 | return array_merge([
55 | ['request', null, InputOption::VALUE_NONE, 'Want a request for this component?'],
56 | ], parent::getOptions());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Commands/MiddlewareCommand.php:
--------------------------------------------------------------------------------
1 | meta = (new NameParser)->parse($this->argumentName());
51 | $name = $this->qualifyClass($this->getNameInput());
52 | $path = $this->getPath($name);
53 |
54 | if ($this->files->exists($path) && $this->optionForce() === false) {
55 | return $this->error($this->type . ' already exists!');
56 | }
57 |
58 | $this->makeDirectory($path);
59 | $this->files->put($path, $this->buildClass($name));
60 |
61 | // check if there is an output handler function
62 | $output_handler = config('generators.output_path_handler');
63 | $this->info($this->type . ' created successfully.');
64 | if (is_callable($output_handler)) {
65 | // output to console from the user defined function
66 | $this->info($output_handler(Str::after($path, '.')));
67 | } else {
68 | // output to console
69 | $this->info('- ' . $path);
70 | }
71 |
72 | // if model is required
73 | if ($this->optionModel() === true || $this->optionModel() === 'true') {
74 | $this->call('generate:model', [
75 | 'name' => $this->getModelName(),
76 | '--plain' => $this->optionPlain(),
77 | '--force' => $this->optionForce(),
78 | '--schema' => $this->optionSchema()
79 | ]);
80 | }
81 | }
82 |
83 | /**
84 | * Build the class with the given name.
85 | *
86 | * @param string $name
87 | * @return string
88 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
89 | * @throws \Bpocallaghan\Generators\Exceptions\GeneratorException
90 | */
91 | protected function buildClass($name)
92 | {
93 | $stub = $this->files->get($this->getStub());
94 |
95 | $this->replaceNamespace($stub, $name);
96 | $this->replaceClassName($stub);
97 | $this->replaceSchema($stub);
98 | $this->replaceTableName($stub);
99 |
100 | return $stub;
101 | }
102 |
103 | /**
104 | * Replace the class name in the stub.
105 | *
106 | * @param string $stub
107 | * @return $this
108 | */
109 | protected function replaceClassName(&$stub)
110 | {
111 | $className = ucwords(Str::camel($this->argumentName()));
112 |
113 | $stub = str_replace('{{class}}', $className, $stub);
114 |
115 | return $this;
116 | }
117 |
118 | /**
119 | * Replace the schema for the stub.
120 | *
121 | * @param string $stub
122 | * @return $this
123 | * @throws \Bpocallaghan\Generators\Exceptions\GeneratorException
124 | */
125 | protected function replaceSchema(&$stub)
126 | {
127 | $schema = '';
128 | if (!$this->optionPlain()) {
129 | if ($schema = $this->optionSchema()) {
130 | $schema = (new SchemaParser)->parse($schema);
131 | }
132 |
133 | $schema = (new SyntaxBuilder)->create($schema, $this->meta);
134 | }
135 |
136 | $stub = str_replace(['{{schema_up}}', '{{schema_down}}'], $schema, $stub);
137 |
138 | return $this;
139 | }
140 |
141 | /**
142 | * Replace the table name in the stub.
143 | *
144 | * @param string $stub
145 | * @return $this
146 | */
147 | protected function replaceTableName(&$stub)
148 | {
149 | $table = $this->meta['table'];
150 |
151 | $stub = str_replace('{{table}}', $table, $stub);
152 |
153 | return $this;
154 | }
155 |
156 | /**
157 | * Get the class name for the Eloquent model generator.
158 | *
159 | * @param null $name
160 | * @return string
161 | */
162 | protected function getModelName($name = null)
163 | {
164 | $name = Str::singular($this->meta['table']);
165 |
166 | $model = '';
167 | $pieces = explode('_', $name);
168 | foreach ($pieces as $k => $str) {
169 | $model = $model . ucwords($str);
170 | }
171 |
172 | return $model;
173 | }
174 |
175 | /**
176 | * Get the path to where we should store the migration.
177 | *
178 | * @param string $name
179 | * @return string
180 | */
181 | protected function getPath($name)
182 | {
183 | return './database/migrations/' . date('Y_m_d_His') . '_' . $this->argumentName() . '.php';
184 | }
185 |
186 | /**
187 | * Get the stub file for the generator.
188 | *
189 | * @return string
190 | */
191 | protected function getStub()
192 | {
193 | return config('generators.stubs.' . strtolower($this->type) . ($this->input->hasOption('plain') && $this->option('plain') ? '_plain' : ''));
194 | }
195 |
196 | /**
197 | * Get the console command options.
198 | *
199 | * @return array
200 | */
201 | protected function getOptions()
202 | {
203 | return array_merge([
204 | ['model', 'm', InputOption::VALUE_OPTIONAL, 'Want a model for this table?', true],
205 | ['schema', 's', InputOption::VALUE_OPTIONAL, 'Optional schema to be attached to the migration', null],
206 | ], parent::getOptions());
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/src/Commands/MigrationPivotCommand.php:
--------------------------------------------------------------------------------
1 | parseName($this->getNameInput());
39 | $path = $this->getPath($name);
40 |
41 | if ($this->files->exists($path) && $this->optionForce() === false) {
42 | return $this->error($this->type . ' already exists!');
43 | }
44 |
45 | // if we need to append the parent models
46 | $modelOne = $this->getModelName($this->argument('tableOne'));
47 | $modelTwo = $this->getModelName($this->argument('tableTwo'));
48 | if ($this->confirm("Add Many To Many Relationship in '{$modelOne}' and '{$modelTwo}' Models? [yes|no]")) {
49 | $this->addRelationshipsInParents();
50 | }
51 |
52 | $this->makeDirectory($path);
53 | $this->files->put($path, $this->buildClass($name));
54 |
55 | // output to console
56 | // check if there is an output handler function
57 | $output_handler = config('generators.output_path_handler');
58 | $this->info($this->type . ' created successfully.');
59 | if (is_callable($output_handler)) {
60 | // output to console from the user defined function
61 | $this->info($output_handler(Str::after($path, '.')));
62 | } else {
63 | // output to console
64 | $this->info('- ' . $path);
65 | }
66 | }
67 |
68 | /**
69 | * Empty 'name' argument
70 | *
71 | * @return string
72 | */
73 | protected function getNameInput()
74 | {
75 | return '';
76 | }
77 |
78 | /**
79 | * Parse the name and format.
80 | *
81 | * @param string $name
82 | * @return string
83 | */
84 | protected function parseName($name)
85 | {
86 | $tables = array_map('Str::singular', $this->getSortedTableNames());
87 | $name = implode('', array_map('ucwords', $tables));
88 | $pieces = explode('_', $name);
89 | $name = implode('', array_map('ucwords', $pieces));
90 |
91 | return "Create{$name}PivotTable";
92 | }
93 |
94 | /**
95 | * Get the destination class path.
96 | *
97 | * @param string $name
98 | * @return string
99 | */
100 | protected function getPath($name = null)
101 | {
102 | return './database/migrations/' . date('Y_m_d_His') . '_create_' . $this->getPivotTableName() . '_pivot_table.php';
103 | }
104 |
105 | /**
106 | * Build the class with the given name.
107 | *
108 | * @param string $name
109 | * @return string
110 | */
111 | protected function buildClass($name)
112 | {
113 | $stub = $this->files->get($this->getStub());
114 |
115 | return $this->replacePivotTableName($stub)
116 | ->replaceSchema($stub)
117 | ->replaceClass($stub, $name);
118 | }
119 |
120 | /**
121 | * Apply the name of the pivot table to the stub.
122 | *
123 | * @param string $stub
124 | * @return $this
125 | */
126 | protected function replacePivotTableName(&$stub)
127 | {
128 | $stub = str_replace('{{pivotTableName}}', $this->getPivotTableName(), $stub);
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Apply the correct schema to the stub.
135 | *
136 | * @param string $stub
137 | * @return $this
138 | */
139 | protected function replaceSchema(&$stub)
140 | {
141 | $tables = $this->getSortedTableNames();
142 |
143 | $stub = str_replace(['{{columnOne}}', '{{columnTwo}}'],
144 | array_merge(array_map('Str::singular', $tables), $tables), $stub);
145 |
146 | $stub = str_replace(['{{tableOne}}', '{{tableTwo}}'],
147 | array_merge(array_map('Str::plural', $tables), $tables), $stub);
148 |
149 | return $this;
150 | }
151 |
152 | /**
153 | * Replace the class name for the given stub.
154 | *
155 | * @param string $stub
156 | * @param string $name
157 | * @return string
158 | */
159 | protected function replaceClass($stub, $name)
160 | {
161 | $class = str_replace($this->getNamespace($name) . '\\', '', $name);
162 |
163 | return str_replace('{{class}}', $class, $stub);
164 | }
165 |
166 | /**
167 | * Get the name of the pivot table.
168 | *
169 | * @return string
170 | */
171 | protected function getPivotTableName()
172 | {
173 | return implode('_', array_map('Str::singular', $this->getSortedTableNames()));
174 | }
175 |
176 | /**
177 | * Sort the two tables in alphabetical order.
178 | *
179 | * @return array
180 | */
181 | protected function getSortedTableNames()
182 | {
183 | $tables = [
184 | strtolower($this->argument('tableOne')),
185 | strtolower($this->argument('tableTwo'))
186 | ];
187 |
188 | sort($tables);
189 |
190 | return $tables;
191 | }
192 |
193 | /**
194 | * Append Many to Many Relationships in Parent Models
195 | */
196 | public function addRelationshipsInParents()
197 | {
198 | $options = config('generators.settings');
199 | if (!$options['model']) {
200 | $this->info('Model files not found.');
201 |
202 | return;
203 | }
204 |
205 | $modelSettings = $options['model'];
206 |
207 | // model names
208 | $modelOne = $this->getModelName($this->argument('tableOne'));
209 | $modelTwo = $this->getModelName($this->argument('tableTwo'));
210 |
211 | // model path
212 | $modelOnePath = $modelSettings['path'] . $modelOne . '.php';
213 | $modelTwoPath = $modelSettings['path'] . $modelTwo . '.php';
214 |
215 | $this->addRelationshipInModel($modelOnePath, $modelTwo, $this->argument('tableTwo'));
216 | $this->addRelationshipInModel($modelTwoPath, $modelOne, $this->argument('tableOne'));
217 | }
218 |
219 | /**
220 | * Insert the many to many relationship in model
221 | * @param $modelPath
222 | * @param $relationshipModel
223 | * @param $tableName
224 | */
225 | private function addRelationshipInModel($modelPath, $relationshipModel, $tableName)
226 | {
227 | // load model
228 | $model = $this->files->get($modelPath);
229 |
230 | // get the position where to insert into file
231 | $index = strlen($model) - strpos(strrev($model), '}') - 1;
232 |
233 | // load many to many stub
234 | $stub = $this->files->get(config('generators.stubs.many_many_relationship'));
235 | $stub = str_replace('{{model}}', $relationshipModel, $stub);
236 | $stub = str_replace('{{relationship}}', Str::camel($tableName), $stub);
237 | //$stub = str_replace('{{relationship}}', strtolower(Str::plural($relationshipModel)), $stub);
238 |
239 | // insert many many stub in model
240 | $model = substr_replace($model, $stub, $index, 0);
241 |
242 | // save model file
243 | $this->files->put($modelPath, $model);
244 |
245 | $this->info("{$relationshipModel} many to many Relationship added in {$modelPath}");
246 | }
247 |
248 | /**
249 | * Get the stub file for the generator.
250 | *
251 | * @return string
252 | */
253 | protected function getStub()
254 | {
255 | return config('generators.stubs.' . strtolower($this->type));
256 | }
257 |
258 | /**
259 | * Get the console command arguments.
260 | *
261 | * @return array
262 | */
263 | protected function getArguments()
264 | {
265 | return [
266 | ['tableOne', InputArgument::REQUIRED, 'The name of the first table.'],
267 | ['tableTwo', InputArgument::REQUIRED, 'The name of the second table.']
268 | ];
269 | }
270 | }
271 |
--------------------------------------------------------------------------------
/src/Commands/ModelCommand.php:
--------------------------------------------------------------------------------
1 | option('migration')) {
41 | $this->call('generate:migration', [
42 | 'name' => $this->getMigrationName(),
43 | '--model' => false,
44 | '--schema' => $this->option('schema')
45 | ]);
46 | }
47 |
48 | if ($this->option('factory')) {
49 | $this->call('generate:factory', [
50 | 'name' => $this->getArgumentNameOnly(),
51 | ]);
52 | }
53 | }
54 |
55 | /**
56 | * Get the name for the migration
57 | *
58 | * @return string
59 | */
60 | private function getMigrationName()
61 | {
62 | $name = $this->getArgumentNameOnly();
63 | $name = preg_replace('/\B([A-Z])/', '_$1', $name);
64 | $name = strtolower($name);
65 | $name = Str::plural($name);
66 |
67 | return "create_{$name}_table";
68 | }
69 |
70 | /**
71 | * Get the console command options.
72 | *
73 | * @return array
74 | */
75 | protected function getOptions()
76 | {
77 | return array_merge([
78 | ['migration', 'm', InputOption::VALUE_NONE, 'Create a new migration file as well.'],
79 | ['factory', 'f', InputOption::VALUE_NONE, 'Create a new factory file as well.'],
80 | ['schema', 's', InputOption::VALUE_OPTIONAL, 'Optional schema to be attached to the migration', null],
81 | ], parent::getOptions());
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Commands/NotificationCommand.php:
--------------------------------------------------------------------------------
1 | copyConfigFile();
31 | $this->copyStubsDirectory();
32 | $this->updateStubsPathsInConfigFile();
33 |
34 | $this->info("The config file has been copied to '" . $this->getConfigPath() . "'.");
35 | $this->info("The stubs have been copied to '{$this->option('path')}'.");
36 | }
37 |
38 | /**
39 | * Copy the config file to the default config folder
40 | */
41 | private function copyConfigFile()
42 | {
43 | $path = $this->getConfigPath();
44 |
45 | // if generatords config already exist
46 | if ($this->files->exists($path) && $this->option('force') === false) {
47 | $this->error("{$path} already exists! Run 'generate:publish-stubs --force' to override the config file.");
48 | die;
49 | }
50 |
51 | File::copy(__DIR__ . '/../config/config.php', $path);
52 | }
53 |
54 | /**
55 | * Copy the stubs directory
56 | */
57 | private function copyStubsDirectory()
58 | {
59 | $path = $this->option('path');
60 |
61 | // if controller stub already exist
62 | if ($this->files->exists($path . DIRECTORY_SEPARATOR . 'controller.stub') && $this->option('force') === false) {
63 | $this->error("Stubs already exists! Run 'generate:publish-stubs --force' to override the stubs.");
64 | die;
65 | }
66 |
67 | File::copyDirectory(__DIR__ . '/../../resources/stubs', $path);
68 | }
69 |
70 | /**
71 | * Update stubs path in the new published config file
72 | */
73 | private function updateStubsPathsInConfigFile()
74 | {
75 | $updated = str_replace('vendor/bpocallaghan/generators/', '',
76 | File::get($this->getConfigPath()));
77 | File::put($this->getConfigPath(), $updated);
78 | }
79 |
80 | /**
81 | * Get the config file path
82 | *
83 | * @return string
84 | */
85 | private function getConfigPath()
86 | {
87 | return config_path('generators.php');
88 | }
89 |
90 | /**
91 | * Get the console command arguments.
92 | *
93 | * @return array
94 | */
95 | protected function getArguments()
96 | {
97 | return [];
98 | }
99 |
100 | /**
101 | * Get the console command options.
102 | *
103 | * @return array
104 | */
105 | protected function getOptions()
106 | {
107 | return [
108 | [
109 | 'path',
110 | null,
111 | InputOption::VALUE_OPTIONAL,
112 | 'Which directory should the templates be copied to?',
113 | 'resources/stubs'
114 | ],
115 | ['force', null, InputOption::VALUE_NONE, 'Warning: Override files if it already exist']
116 | ];
117 | }
118 |
119 | /**
120 | * Get the stub file for the generator.
121 | *
122 | * @return string
123 | */
124 | protected function getStub()
125 | {
126 | //
127 | }
128 | }
--------------------------------------------------------------------------------
/src/Commands/RepositoryCommand.php:
--------------------------------------------------------------------------------
1 | option('contract')) {
38 | parent::handle();
39 | } else {
40 | $this->call('generate:repository', [
41 | 'name' => $this->argumentName(),
42 | '--stub' => 'repository_contract',
43 | ]);
44 | }
45 | }
46 |
47 | /**
48 | * Get the console command options.
49 | *
50 | * @return array
51 | */
52 | protected function getOptions()
53 | {
54 | return array_merge([
55 | ['contract', 'c', InputOption::VALUE_NONE, 'Use the implements Contract Stub.'],
56 | ], parent::getOptions());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Commands/RequestCommand.php:
--------------------------------------------------------------------------------
1 | resource = $this->getResourceOnly();
42 | $this->settings = config('generators.defaults');
43 |
44 | $this->callModel();
45 | $this->callView();
46 | $this->callRepository();
47 | $this->callController();
48 | $this->callMigration();
49 | $this->callSeeder();
50 | $this->callTest();
51 | $this->callFactory();
52 | $this->callMigrate();
53 |
54 | // confirm dump autoload
55 | if ($this->confirm("Run 'composer dump-autoload'?")) {
56 | $this->composer->dumpAutoloads();
57 | }
58 |
59 | $this->info('All Done!');
60 | $this->info('Remember to add ' . "`Route::resource('" . str_replace(
61 | '_',
62 | '-',
63 | $this->getCollectionName()
64 | ) . "', '" . $this->getResourceControllerName() . "');`" . ' in `routes\\web.php`');
65 | }
66 |
67 | /**
68 | * Call the generate:model command
69 | */
70 | private function callModel(): void
71 | {
72 | $name = $this->getModelName();
73 |
74 | $resourceString = $this->getResourceOnly();
75 | $resourceStringLength = strlen($this->getResourceOnly());
76 |
77 | if ($resourceStringLength > 18) {
78 | $ans = $this->confirm("Your resource {$resourceString} may have too many characters to use for many to many relationships. The length is {$resourceStringLength}. Continue?");
79 | if ($ans === false) {
80 | echo "generate:resource cancelled!";
81 | die;
82 | }
83 | }
84 |
85 | if ($this->confirm("Create a $name model?")) {
86 | $this->callCommandFile('model');
87 | }
88 | }
89 |
90 | /**
91 | * Generate the resource views
92 | */
93 | private function callView(): void
94 | {
95 | if ($this->confirm("Create crud views for the $this->resource resource?")) {
96 | $views = config('generators.resource_views');
97 | foreach ($views as $key => $name) {
98 | $resource = $this->argument('resource');
99 | if (Str::contains($resource, '.')) {
100 | $resource = str_replace('.', '/', $resource);
101 | }
102 |
103 | $this->callCommandFile(
104 | 'view',
105 | $this->getViewPath($resource),
106 | $key . $this->option('view'),
107 | ['--name' => $name]
108 | );
109 | }
110 | }
111 | }
112 |
113 | /**
114 | * Generate the Repository / Contract Pattern files
115 | */
116 | private function callRepository(): void
117 | {
118 | // check the config
119 | if (config('generators.settings.controller.repository_contract')) {
120 | if ($this->confirm("Create a repository and contract for the $this->resource resource?")) {
121 | $name = $this->getModelName();
122 |
123 | $this->repositoryContract = true;
124 |
125 | $this->callCommandFile('contract', $name);
126 | $this->callCommandFile('repository', $name);
127 |
128 | //$contract = $name . config('generators.settings.contract.postfix');
129 | //$this->callCommandFile('repository', $name, ['--contract' => $contract]);
130 | }
131 | }
132 | }
133 |
134 | /**
135 | * Generate the resource controller
136 | */
137 | private function callController(): void
138 | {
139 | $name = $this->getResourceControllerName();
140 |
141 | if ($this->confirm("Create a controller ($name) for the $this->resource resource?")) {
142 | $arg = $this->getArgumentResource();
143 | $name = substr_replace(
144 | $arg,
145 | Str::plural($this->resource),
146 | strrpos($arg, $this->resource),
147 | strlen($this->resource)
148 | );
149 |
150 | if ($this->repositoryContract) {
151 | $this->callCommandFile('controller', $name, 'controller_repository');
152 | } else {
153 |
154 | // if admin - update stub
155 | if (Str::contains($name, 'admin.') || $this->option('controller') === 'admin') {
156 | $this->callCommandFile('controller', $name, 'controller_admin');
157 | } else {
158 | $this->callCommandFile('controller', $name, 'controller');
159 | }
160 | }
161 | }
162 | }
163 |
164 | /**
165 | * Call the generate:migration command
166 | */
167 | private function callMigration(): void
168 | {
169 | $name = $this->getMigrationName($this->option('migration'));
170 |
171 | if ($this->confirm("Create a migration ($name) for the $this->resource resource?")) {
172 | $this->callCommand('migration', $name, [
173 | '--model' => false,
174 | '--schema' => $this->option('schema')
175 | ]);
176 | }
177 | }
178 |
179 | /**
180 | * Call the generate:seed command
181 | */
182 | private function callSeeder(): void
183 | {
184 | $name = $this->getSeederName() . config('generators.settings.seeder.postfix');
185 |
186 | if ($this->confirm("Create a seeder ($name) for the $this->resource resource?")) {
187 | $this->callCommandFile('seeder');
188 | }
189 | }
190 |
191 | /**
192 | * Call the generate:test command
193 | */
194 | private function callTest(): void
195 | {
196 | $name = $this->getModelName() . 'Test';
197 |
198 | if ($this->confirm("Create a test ($name) for the $this->resource resource?")) {
199 | // feature test
200 | $this->callCommandFile('test', Str::plural($name));
201 |
202 | // unit test
203 | $this->call('generate:file', [
204 | 'name' => $name,
205 | '--type' => 'test',
206 | '--unit' => 'Unit',
207 | ]);
208 | }
209 | }
210 |
211 | /**
212 | * Call the generate:factory command
213 | */
214 | private function callFactory(): void
215 | {
216 | $name = $this->getModelName() . 'Factory';
217 |
218 | if ($this->confirm("Create a factory ($name) for the $this->resource resource?")) {
219 | $this->callCommandFile('factory', $name);
220 | }
221 | }
222 |
223 | /**
224 | * Call the migrate command
225 | */
226 | protected function callMigrate(): void
227 | {
228 | if ($this->confirm('Migrate the database?')) {
229 | $this->call('migrate');
230 | }
231 | }
232 |
233 | /**
234 | * @param $command
235 | * @param $name
236 | * @param array $options
237 | */
238 | private function callCommand($command, $name, $options = []): void
239 | {
240 | $options = array_merge($options, [
241 | 'name' => $name,
242 | '--plain' => $this->option('plain'),
243 | '--force' => $this->option('force')
244 | ]);
245 |
246 | $this->call('generate:' . $command, $options);
247 | }
248 |
249 | /**
250 | * Call the generate:file command to generate the given file
251 | *
252 | * @param $type
253 | * @param null $name
254 | * @param null $stub
255 | * @param array $options
256 | */
257 | private function callCommandFile($type, $name = null, $stub = null, $options = []): void
258 | {
259 | $this->call('generate:file', array_merge($options, [
260 | 'name' => ($name ? $name : $this->argument('resource')),
261 | '--type' => $type,
262 | '--force' => $this->optionForce(),
263 | '--plain' => $this->optionPlain(),
264 | '--stub' => ($stub ?: $this->optionStub()),
265 | ]));
266 | }
267 |
268 | /**
269 | * The resource argument
270 | * Lowercase and singular each word
271 | *
272 | * @return array|mixed|string
273 | */
274 | private function getArgumentResource()
275 | {
276 | $name = $this->argument('resource');
277 | if (Str::contains($name, '/')) {
278 | $name = str_replace('/', '.', $name);
279 | }
280 |
281 | if (Str::contains($name, '\\')) {
282 | $name = str_replace('\\', '.', $name);
283 | }
284 |
285 | // lowecase and singular
286 | $name = strtolower(Str::singular($name));
287 |
288 | return $name;
289 | }
290 |
291 | /**
292 | * If there are '.' in the name, get the last occurence
293 | *
294 | * @return string
295 | */
296 | private function getResourceOnly()
297 | {
298 | $name = $this->getArgumentResource();
299 | if (!Str::contains($name, '.')) {
300 | return $name;
301 | }
302 |
303 | return substr($name, strripos($name, '.') + 1);
304 | }
305 |
306 | /**
307 | * Get the Controller name for the resource
308 | *
309 | * @return string
310 | */
311 | private function getResourceControllerName(): string
312 | {
313 | return $this->getControllerName(
314 | Str::plural($this->resource),
315 | false
316 | ) . config('generators.settings.controller.postfix');
317 | }
318 |
319 | /**
320 | * Get the name for the migration
321 | *
322 | * @param null $name
323 | * @return string
324 | */
325 | private function getMigrationName($name = null): string
326 | {
327 | return 'create_' . Str::plural($this->getResourceName($name)) . '_table';
328 | }
329 |
330 | /**
331 | * Get the console command arguments.
332 | *
333 | * @return array
334 | */
335 | protected function getArguments()
336 | {
337 | return [
338 | ['resource', InputArgument::REQUIRED, 'The name of the resource being generated.'],
339 | ];
340 | }
341 |
342 | /**
343 | * Get the console command options.
344 | *
345 | * @return array
346 | */
347 | protected function getOptions()
348 | {
349 | return array_merge(parent::getOptions(), [
350 | [
351 | 'view',
352 | null,
353 | InputOption::VALUE_OPTIONAL,
354 | 'Specify the stub for the views',
355 | null
356 | ],
357 | [
358 | 'controller',
359 | null,
360 | InputOption::VALUE_OPTIONAL,
361 | 'Specify the stub for the controller',
362 | null
363 | ],
364 | ['migration', null, InputOption::VALUE_OPTIONAL, 'Optional migration name', null],
365 | [
366 | 'schema',
367 | 's',
368 | InputOption::VALUE_OPTIONAL,
369 | 'Optional schema to be attached to the migration',
370 | null
371 | ],
372 | ]);
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/src/Commands/SeederCommand.php:
--------------------------------------------------------------------------------
1 | mergeConfigFrom($configPath, 'generators');
56 |
57 | // register all the artisan commands
58 | $this->registerCommand(PublishCommand::class, 'publish');
59 |
60 | $this->registerCommand(ModelCommand::class, 'model');
61 | $this->registerCommand(ViewCommand::class, 'view');
62 | $this->registerCommand(ControllerCommand::class, 'controller');
63 |
64 | $this->registerCommand(RequestCommand::class, 'request');
65 | $this->registerCommand(MiddlewareCommand::class, 'middleware');
66 |
67 | $this->registerCommand(SeederCommand::class, 'seeder');
68 | $this->registerCommand(MigrationCommand::class, 'migration');
69 | $this->registerCommand(MigrationPivotCommand::class, 'migrate.pivot');
70 |
71 | $this->registerCommand(NotificationCommand::class, 'notification');
72 |
73 | $this->registerCommand(EventCommand::class, 'event');
74 | $this->registerCommand(ListenerCommand::class, 'listener');
75 | $this->registerCommand(EventGenerateCommand::class, 'event.generate');
76 |
77 | $this->registerCommand(TraitCommand::class, 'trait');
78 | $this->registerCommand(ContractCommand::class, 'contract');
79 | $this->registerCommand(RepositoryCommand::class, 'repository');
80 |
81 | $this->registerCommand(LivewireCommand::class, 'livewire');
82 | $this->registerCommand(ComponentCommand::class, 'component');
83 |
84 | $this->registerCommand(TestCommand::class, 'test');
85 | $this->registerCommand(FactoryCommand::class, 'factory');
86 |
87 | $this->registerCommand(JobCommand::class, 'job');
88 | $this->registerCommand(ConsoleCommand::class, 'console');
89 |
90 | $this->registerCommand(ExceptionCommand::class, 'exception');
91 |
92 | $this->registerCommand(ResourceCommand::class, 'resource');
93 |
94 | $this->registerCommand(FileCommand::class, 'file');
95 | }
96 |
97 | /**
98 | * Register a singleton command
99 | *
100 | * @param $class
101 | * @param $command
102 | */
103 | private function registerCommand($class, $command)
104 | {
105 | $this->app->singleton($this->commandPath . $command, function ($app) use ($class) {
106 | return $app[$class];
107 | });
108 |
109 | $this->commands($this->commandPath . $command);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Migrations/NameParser.php:
--------------------------------------------------------------------------------
1 | $this->getAction($segments),
24 | 'table' => $this->getTableName($segments)
25 | ];
26 | }
27 |
28 | /**
29 | * Calculate the table name.
30 | *
31 | * @param array $segments
32 | *
33 | * @return array
34 | */
35 | private function getTableName($segments)
36 | {
37 | $tableName = [];
38 |
39 | foreach ($segments as $segment) {
40 | if ($this->isConnectingWord($segment)) {
41 | break;
42 | }
43 |
44 | $tableName[] = $segment;
45 | }
46 |
47 | return implode('_', array_reverse($tableName));
48 | }
49 |
50 | /**
51 | * Determine the user's desired action for the migration.
52 | *
53 | * @param array $segments
54 | *
55 | * @return mixed
56 | */
57 | private function getAction(&$segments)
58 | {
59 | return $this->normalizeActionName(array_pop($segments));
60 | }
61 |
62 | /**
63 | * Normalize the user's chosen action to name to
64 | * something that we recognize.
65 | *
66 | * @param string $action
67 | *
68 | * @return string
69 | */
70 | private function normalizeActionName($action)
71 | {
72 | switch ($action) {
73 | case 'create':
74 | case 'make':
75 | return 'create';
76 | case 'delete':
77 | case 'destroy':
78 | case 'drop':
79 | return 'remove';
80 | case 'add':
81 | case 'append':
82 | case 'update':
83 | case 'insert':
84 | return 'add';
85 | default:
86 | return $action;
87 | }
88 | }
89 |
90 | /**
91 | * Determine if the current segment is a connecting word.
92 | *
93 | * @param string $segment
94 | *
95 | * @return bool
96 | */
97 | private function isConnectingWord($segment)
98 | {
99 | $connectors = ['to', 'from', 'and', 'with', 'for', 'in', 'of', 'on'];
100 |
101 | return in_array($segment, $connectors);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Migrations/SchemaParser.php:
--------------------------------------------------------------------------------
1 | splitIntoFields($schema);
27 |
28 | foreach ($fields as $field) {
29 | $segments = $this->parseSegments($field);
30 |
31 | if ($this->fieldNeedsForeignConstraint($segments)) {
32 | unset($segments['options']['foreign']);
33 |
34 | // If the user wants a foreign constraint, then
35 | // we'll first add the regular field.
36 | $this->addField($segments);
37 |
38 | // And then add another field for the constraint.
39 | $this->addForeignConstraint($segments);
40 |
41 | continue;
42 | }
43 |
44 | $this->addField($segments);
45 | }
46 |
47 | return $this->schema;
48 | }
49 |
50 | /**
51 | * Add a field to the schema array.
52 | *
53 | * @param array $field
54 | *
55 | * @return $this
56 | */
57 | private function addField($field)
58 | {
59 | $this->schema[] = $field;
60 |
61 | return $this;
62 | }
63 |
64 | /**
65 | * Get an array of fields from the given schema.
66 | *
67 | * @param string $schema
68 | *
69 | * @return array
70 | */
71 | private function splitIntoFields($schema)
72 | {
73 | return preg_split('/,\s?(?![^()]*\))/', $schema);
74 | }
75 |
76 | /**
77 | * Get the segments of the schema field.
78 | *
79 | * @param string $field
80 | *
81 | * @return array
82 | */
83 | private function parseSegments($field)
84 | {
85 | $segments = explode(':', $field);
86 |
87 | $name = array_shift($segments);
88 | $type = array_shift($segments);
89 | $arguments = [];
90 | $options = $this->parseOptions($segments);
91 |
92 | // Do we have arguments being used here?
93 | // Like: string(100)
94 | if (preg_match('/(.+?)\(([^)]+)\)/', $type, $matches)) {
95 | $type = $matches[1];
96 | $arguments = explode(',', $matches[2]);
97 | }
98 |
99 | return compact('name', 'type', 'arguments', 'options');
100 | }
101 |
102 | /**
103 | * Parse any given options into something usable.
104 | *
105 | * @param array $options
106 | *
107 | * @return array
108 | */
109 | private function parseOptions($options)
110 | {
111 | if (empty($options)) {
112 | return [];
113 | }
114 |
115 | foreach ($options as $option) {
116 | if (Str::contains($option, '(')) {
117 | preg_match('/([a-z]+)\(([^\)]+)\)/i', $option, $matches);
118 |
119 | $results[$matches[1]] = $matches[2];
120 | }
121 | else {
122 | $results[$option] = true;
123 | }
124 | }
125 |
126 | return $results;
127 | }
128 |
129 | /**
130 | * Add a foreign constraint field to the schema.
131 | *
132 | * @param array $segments
133 | */
134 | private function addForeignConstraint($segments)
135 | {
136 | $string = sprintf("%s:foreign:references('id'):on('%s')", $segments['name'], $this->getTableNameFromForeignKey($segments['name']));
137 |
138 | $this->addField($this->parseSegments($string));
139 | }
140 |
141 | /**
142 | * Try to figure out the name of a table from a foreign key.
143 | * Ex: user_id => users
144 | *
145 | * @param string $key
146 | *
147 | * @return string
148 | */
149 | private function getTableNameFromForeignKey($key)
150 | {
151 | return Str::plural(str_replace('_id', '', $key));
152 | }
153 |
154 | /**
155 | * Determine if the user wants a foreign constraint for the field.
156 | *
157 | * @param array $segments
158 | *
159 | * @return bool
160 | */
161 | private function fieldNeedsForeignConstraint($segments)
162 | {
163 | return array_key_exists('foreign', $segments['options']);
164 | }
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/src/Migrations/SyntaxBuilder.php:
--------------------------------------------------------------------------------
1 | createSchemaForUpMethod($schema, $meta);
28 | $down = $this->createSchemaForDownMethod($schema, $meta);
29 |
30 | return compact('up', 'down');
31 | }
32 |
33 | /**
34 | * Create the schema for the "up" method.
35 | *
36 | * @param string $schema
37 | * @param array $meta
38 | *
39 | * @return string
40 | * @throws GeneratorException
41 | */
42 | private function createSchemaForUpMethod($schema, $meta)
43 | {
44 | $fields = $this->constructSchema($schema);
45 |
46 | if ($meta['action'] == 'create') {
47 | return $this->insert($fields)->into($this->getCreateSchemaWrapper());
48 | }
49 |
50 | if ($meta['action'] == 'add') {
51 | return $this->insert($fields)->into($this->getChangeSchemaWrapper());
52 | }
53 |
54 | if ($meta['action'] == 'remove') {
55 | $fields = $this->constructSchema($schema, 'Drop');
56 |
57 | return $this->insert($fields)->into($this->getChangeSchemaWrapper());
58 | }
59 |
60 | // Otherwise, we have no idea how to proceed.
61 | throw new GeneratorException;
62 | }
63 |
64 | /**
65 | * Construct the syntax for a down field.
66 | *
67 | * @param array $schema
68 | * @param array $meta
69 | *
70 | * @return string
71 | * @throws GeneratorException
72 | */
73 | private function createSchemaForDownMethod($schema, $meta)
74 | {
75 | // If the user created a table, then for the down
76 | // method, we should drop it.
77 | if ($meta['action'] == 'create') {
78 | return sprintf("Schema::dropIfExists('%s');", $meta['table']);
79 | }
80 |
81 | // If the user added columns to a table, then for
82 | // the down method, we should remove them.
83 | if ($meta['action'] == 'add') {
84 | $fields = $this->constructSchema($schema, 'Drop');
85 |
86 | return $this->insert($fields)->into($this->getChangeSchemaWrapper());
87 | }
88 |
89 | // If the user removed columns from a table, then for
90 | // the down method, we should add them back on.
91 | if ($meta['action'] == 'remove') {
92 | $fields = $this->constructSchema($schema);
93 |
94 | return $this->insert($fields)->into($this->getChangeSchemaWrapper());
95 | }
96 |
97 | // Otherwise, we have no idea how to proceed.
98 | throw new GeneratorException;
99 | }
100 |
101 | /**
102 | * Store the given template, to be inserted somewhere.
103 | *
104 | * @param string $template
105 | *
106 | * @return $this
107 | */
108 | private function insert($template)
109 | {
110 | $this->template = $template;
111 |
112 | return $this;
113 | }
114 |
115 | /**
116 | * Get the stored template, and insert into the given wrapper.
117 | *
118 | * @param string $wrapper
119 | * @param string $placeholder
120 | *
121 | * @return mixed
122 | */
123 | private function into($wrapper, $placeholder = 'schema_up')
124 | {
125 | return str_replace('{{' . $placeholder . '}}', $this->template, $wrapper);
126 | }
127 |
128 | /**
129 | * Get the wrapper template for a "create" action.
130 | *
131 | * @return string
132 | */
133 | private function getCreateSchemaWrapper()
134 | {
135 | return file_get_contents(config('generators.stubs.schema_create'));
136 | }
137 |
138 | /**
139 | * Get the wrapper template for an "add" action.
140 | *
141 | * @return string
142 | */
143 | private function getChangeSchemaWrapper()
144 | {
145 | return file_get_contents(config('generators.stubs.schema_change'));
146 | }
147 |
148 | /**
149 | * Construct the schema fields.
150 | *
151 | * @param array $schema
152 | * @param string $direction
153 | *
154 | * @return array
155 | */
156 | private function constructSchema($schema, $direction = 'Add')
157 | {
158 | if (!$schema) {
159 | return '';
160 | }
161 |
162 | $fields = array_map(function ($field) use ($direction) {
163 | $method = "{$direction}Column";
164 |
165 | return $this->$method($field);
166 | }, $schema);
167 |
168 | return implode("\n" . str_repeat(' ', 12), $fields);
169 | }
170 |
171 | /**
172 | * Construct the syntax to add a column.
173 | *
174 | * @param string $field
175 | *
176 | * @return string
177 | */
178 | private function addColumn($field)
179 | {
180 | $syntax = sprintf("\$table->%s('%s')", $field['type'], $field['name']);
181 |
182 | // If there are arguments for the schema type, like decimal('amount', 5, 2)
183 | // then we have to remember to work those in.
184 | if ($field['arguments']) {
185 | $syntax = substr($syntax, 0, -1) . ', ';
186 |
187 | $syntax .= implode(', ', $field['arguments']) . ')';
188 | }
189 |
190 | foreach ($field['options'] as $method => $value) {
191 | $syntax .= sprintf("->%s(%s)", $method, $value === true ? '' : $value);
192 | }
193 |
194 | return $syntax .= ';';
195 | }
196 |
197 | /**
198 | * Construct the syntax to drop a column.
199 | *
200 | * @param string $field
201 | *
202 | * @return string
203 | */
204 | private function dropColumn($field)
205 | {
206 | return sprintf("\$table->dropColumn('%s');", $field['name']);
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/src/Traits/ArgumentsOptions.php:
--------------------------------------------------------------------------------
1 | settings) {
14 | return str_replace($this->settings['postfix'], '', $this->argument('name'));
15 | }
16 |
17 | return $this->argument('name');
18 | }
19 |
20 | /**
21 | * Get the value for the force option
22 | */
23 | protected function optionForce(): bool|array|string|null
24 | {
25 | return $this->option('force');
26 | }
27 |
28 | /**
29 | * Get the value for the plain option
30 | */
31 | protected function optionPlain(): bool|array|string|null
32 | {
33 | return $this->option('plain');
34 | }
35 |
36 | /**
37 | * Get the value for the stub option
38 | */
39 | protected function optionStub(): bool|array|string|null
40 | {
41 | return $this->option('stub');
42 | }
43 |
44 | /**
45 | * Get the value for the model option
46 | */
47 | protected function optionModel(): bool|array|string|null
48 | {
49 | return $this->option('model');
50 | }
51 |
52 | /**
53 | * Get the value for the schema option
54 | */
55 | protected function optionSchema(): bool|array|string|null
56 | {
57 | return $this->option('schema');
58 | }
59 |
60 | /**
61 | * Get the value for the name option
62 | */
63 | protected function optionName(): bool|array|string|null
64 | {
65 | return $this->option('name');
66 | }
67 |
68 | /**
69 | * Get the value for the name option
70 | */
71 | protected function optionTest(): bool|array|string|null
72 | {
73 | return $this->option('test');
74 | }
75 |
76 | /**
77 | * Get the value for the extra option
78 | */
79 | protected function optionExtra(): bool|array|string|null
80 | {
81 | return $this->option($this->extraOption);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Traits/Settings.php:
--------------------------------------------------------------------------------
1 | option('type');
20 | $options = config('generators.settings');
21 |
22 | $found = false;
23 | // loop through the settings and find the type key
24 | foreach ($options as $key => $settings) {
25 | if ($type == $key) {
26 | $found = true;
27 | break;
28 | }
29 | }
30 |
31 | if ($found === false) {
32 | $this->error('Oops!, no settings key by the type name provided');
33 | exit;
34 | }
35 |
36 | // set the default keys and values if they do not exist
37 | $defaults = config('generators.defaults');
38 | foreach ($defaults as $key => $value) {
39 | if (!isset($settings[$key])) {
40 | $settings[$key] = $defaults[$key];
41 | }
42 | }
43 |
44 | $this->settings = $settings;
45 | }
46 |
47 | /**
48 | * Return false or the value for given key from the settings
49 | *
50 | * @param $key
51 | *
52 | * @return bool
53 | */
54 | public function settingsKey($key)
55 | {
56 | if (is_array($this->settings) == false || isset($this->settings[$key]) == false) {
57 | return false;
58 | }
59 |
60 | return $this->settings[$key];
61 | }
62 |
63 | /**
64 | * Get the directory format setting's value
65 | */
66 | protected function settingsDirectoryFormat()
67 | {
68 | return $this->settingsKey('directory_format') ? $this->settings['directory_format'] : false;
69 | }
70 |
71 | /**
72 | * Get the directory format setting's value
73 | */
74 | protected function settingsDirectoryNamespace()
75 | {
76 | return $this->settingsKey('directory_namespace') ? $this->settings['directory_namespace'] : false;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/config/config.php:
--------------------------------------------------------------------------------
1 | ['app', 'website', 'admin'],
13 |
14 | /*
15 | |--------------------------------------------------------------------------
16 | | The default keys and values for the settings of each type to be generated
17 | |--------------------------------------------------------------------------
18 | */
19 |
20 | 'defaults' => [
21 | 'namespace' => '',
22 | 'path' => './app/',
23 | 'prefix' => '',
24 | 'postfix' => '',
25 | 'file_type' => '.php',
26 | 'dump_autoload' => false,
27 | 'directory_format' => '',
28 | 'directory_namespace' => false,
29 | ],
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Types of files that can be generated
34 | |--------------------------------------------------------------------------
35 | */
36 |
37 | 'settings' => [
38 | 'view' => [
39 | 'path' => './resources/views/',
40 | 'file_type' => '.blade.php',
41 | 'directory_format' => 'strtolower',
42 | 'directory_namespace' => true
43 | ],
44 | 'model' => ['namespace' => '\Models', 'path' => './app/Models/'],
45 | 'controller' => [
46 | 'namespace' => '\Http\Controllers',
47 | 'path' => './app/Http/Controllers/',
48 | 'postfix' => 'Controller',
49 | 'directory_namespace' => true,
50 | 'dump_autoload' => false,
51 | 'repository_contract' => false,
52 | ],
53 | 'request' => [
54 | 'namespace' => '\Http\Requests',
55 | 'path' => './app/Http/Requests/',
56 | 'postfix' => 'Request',
57 | 'directory_namespace' => true,
58 | ],
59 | 'seeder' => ['path' => './database/seeders/', 'postfix' => 'TableSeeder'],
60 | 'migration' => ['path' => './database/migrations/'],
61 | 'notification' => [
62 | 'directory_namespace' => true,
63 | 'namespace' => '\Notifications',
64 | 'path' => './app/Notifications/'
65 | ],
66 | 'event' => [
67 | 'directory_namespace' => true,
68 | 'namespace' => '\Events',
69 | 'path' => './app/Events/'
70 | ],
71 | 'listener' => [
72 | 'directory_namespace' => true,
73 | 'namespace' => '\Listeners',
74 | 'path' => './app/Listeners/'
75 | ],
76 | 'trait' => [
77 | 'directory_namespace' => true,
78 | ],
79 | 'job' => [
80 | 'directory_namespace' => true,
81 | 'namespace' => '\Jobs',
82 | 'path' => './app/Jobs/'
83 | ],
84 | 'console' => [
85 | 'directory_namespace' => true,
86 | 'namespace' => '\Console\Commands',
87 | 'path' => './app/Console/Commands/'
88 | ],
89 | 'exception' => [
90 | 'directory_namespace' => true,
91 | 'namespace' => '\Exceptions',
92 | 'path' => './app/Exceptions/'
93 | ],
94 | 'middleware' => [
95 | 'directory_namespace' => true,
96 | 'namespace' => '\Http\Middleware',
97 | 'path' => './app/Http/Middleware/'
98 | ],
99 | 'repository' => [
100 | 'directory_namespace' => true,
101 | 'postfix' => 'Repository',
102 | 'namespace' => '\Repositories',
103 | 'path' => './app/Repositories/'
104 | ],
105 | 'contract' => [
106 | 'directory_namespace' => true,
107 | 'namespace' => '\Contracts',
108 | 'postfix' => 'Repository',
109 | 'path' => './app/Contracts/',
110 | ],
111 | 'factory' => [
112 | 'postfix' => 'Factory',
113 | 'path' => './database/factories/',
114 | ],
115 | 'test' => [
116 | 'directory_namespace' => true,
117 | 'namespace' => '\Tests',
118 | 'postfix' => 'Test',
119 | 'path' => './tests/',
120 | ],
121 | 'livewire' => [
122 | 'namespace' => '\Http\Livewire',
123 | 'path' => './app/Http/Livewire/',
124 | 'postfix' => '',
125 | 'directory_namespace' => true,
126 | ],
127 | 'livewire_view' => [
128 | 'path' => './resources/views/livewire/',
129 | 'file_type' => '.blade.php',
130 | 'directory_format' => 'strtolower',
131 | 'directory_namespace' => true
132 | ],
133 | 'component' => [
134 | 'namespace' => '\View\Components',
135 | 'path' => './app/View/Components/',
136 | 'postfix' => '',
137 | 'directory_namespace' => true,
138 | ],
139 | 'component_view' => [
140 | 'path' => './resources/views/components/',
141 | 'file_type' => '.blade.php',
142 | 'directory_format' => 'strtolower',
143 | 'directory_namespace' => true
144 | ],
145 | ],
146 |
147 | /*
148 | |--------------------------------------------------------------------------
149 | | Resource Views [stub_key | name of the file]
150 | |--------------------------------------------------------------------------
151 | */
152 |
153 | 'resource_views' => [
154 | 'view_index' => 'index',
155 | //'view_create' => 'create',
156 | //'view_edit' => 'edit',
157 | 'view_show' => 'show',
158 | 'view_create_edit' => 'create_edit',
159 | ],
160 |
161 | /*
162 | |--------------------------------------------------------------------------
163 | | Where the stubs for the generators are stored
164 | |--------------------------------------------------------------------------
165 | */
166 |
167 | 'stubs' => [
168 | 'example' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/example.stub',
169 | 'model' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/model.stub',
170 | 'model_plain' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/model.plain.stub',
171 | 'migration' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/migration.stub',
172 | 'migration_plain' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/migration.plain.stub',
173 | 'controller' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/controller.stub',
174 | 'controller_plain' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/controller.plain.stub',
175 | 'controller_admin' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/controller_admin.stub',
176 | 'controller_repository' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/controller_repository.stub',
177 | 'request' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/request.stub',
178 | 'pivot' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/pivot.stub',
179 | 'seeder' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/seeder.stub',
180 | 'seeder_plain' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/seeder.plain.stub',
181 | 'view' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.stub',
182 | 'view_index' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.index.stub',
183 | 'view_indexb3' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.index.b3.stub',
184 | 'view_show' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.show.stub',
185 | 'view_showb3' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.show.b3.stub',
186 | //'view_create' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.create.stub',
187 | //'view_edit' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.edit.stub',
188 | 'view_create_edit' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.create_edit.stub',
189 | 'view_create_editb3' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/view.create_edit.b3.stub',
190 | 'schema_create' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/schema_create.stub',
191 | 'schema_change' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/schema_change.stub',
192 | 'notification' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/notification.stub',
193 | 'event' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/event.stub',
194 | 'listener' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/listener.stub',
195 | 'many_many_relationship' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/many_many_relationship.stub',
196 | 'trait' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/trait.stub',
197 | 'job' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/job.stub',
198 | 'console' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/console.stub',
199 | 'exception' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/exception.stub',
200 | 'middleware' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/middleware.stub',
201 | 'repository' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/repository.stub',
202 | 'repository_contract' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/repository.contract.stub',
203 | 'contract' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/contract.stub',
204 | 'factory' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/factory.stub',
205 | 'test' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/test.stub',
206 | 'livewire' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/livewire.stub',
207 | 'livewire_view' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/livewire.view.stub',
208 | 'component' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/component.stub',
209 | 'component_view' => base_path() . '/vendor/bpocallaghan/generators/resources/stubs/component.view.stub',
210 | ]
211 | ];
212 |
--------------------------------------------------------------------------------
/tests/ComponentCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:component foo');
11 | $this->assertFileExists('app/View/Components/Foo.php');
12 | $this->assertFileExists('resources/views/components/foo.blade.php');
13 |
14 | $this->artisan('generate:component Bar');
15 | $this->assertFileExists('app/View/Components/Bar.php');
16 | $this->assertFileExists('resources/views/components/bar.blade.php');
17 |
18 | $this->artisan('generate:component FooBar');
19 | $this->assertFileExists('app/View/Components/FooBar.php');
20 | $this->assertFileExists('resources/views/components/foo-bar.blade.php');
21 |
22 | $this->artisan('generate:component Foo/Bar');
23 | $this->assertFileExists('app/View/Components/Foo/Bar.php');
24 | $this->assertFileExists('resources/views/components/foo/bar.blade.php');
25 |
26 | $this->artisan('generate:component folder.foo');
27 | $this->assertFileExists('app/View/Components/Folder/Foo.php');
28 | $this->assertFileExists('resources/views/components/folder/foo.blade.php');
29 |
30 | $this->artisan('generate:component folder.foo-bar');
31 | $this->assertFileExists('app/View/Components/Folder/FooBar.php');
32 | $this->assertFileExists('resources/views/components/folder/foo-bar.blade.php');
33 | }
34 |
35 | /** @test */
36 | public function generate_component_test_option()
37 | {
38 | $this->artisan('generate:component Foo --test');
39 | $this->assertFileExists('app/View/Components/Foo.php');
40 | $this->assertFileExists('resources/views/components/foo.blade.php');
41 | $this->assertFileExists('tests/Unit/View/Components/FooTest.php');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/ConsoleCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:console SendEmails');
11 | $this->assertFileExists('app/Console/Commands/SendEmails.php');
12 | }
13 |
14 | /** @test */
15 | public function generate_console_with_option_test()
16 | {
17 | $this->artisan('generate:job NotifyApi --test');
18 | $this->assertFileExists('app/Jobs/NotifyApi.php');
19 | $this->assertFileExists('tests/Unit/Jobs/NotifyApiTest.php');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/ContractCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:contract Cache');
11 | $this->assertFileExists('app/Contracts/CacheRepository.php');
12 |
13 | $this->artisan('generate:contract PostsRepository');
14 | $this->assertFileExists('app/Contracts/PostsRepository.php');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/ControllerCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:controller test');
11 | $this->assertFileExists('app/Http/Controllers/TestController.php');
12 | }
13 |
14 | /** @test */
15 | public function uppercase_file_name()
16 | {
17 | $this->artisan('generate:controller foo.bar');
18 | $this->assertFileExists('app/Http/Controllers/Foo/BarController.php');
19 |
20 | $this->artisan('generate:controller fooBar');
21 | $this->assertFileExists('app/Http/Controllers/FooBarController.php');
22 | }
23 |
24 | /** @test */
25 | public function option_plain_stub()
26 | {
27 | $this->artisan('generate:controller plain --plain');
28 | $this->assertFileExists('app/Http/Controllers/PlainController.php');
29 | }
30 |
31 | /** @test */
32 | public function do_not_include_controller_suffix_if_already_in_name()
33 | {
34 | $this->artisan('generate:controller SuffixController');
35 | $this->assertFileExists('app/Http/Controllers/SuffixController.php');
36 | }
37 |
38 | /** @test */
39 | public function generate_controller_with_option_test()
40 | {
41 | $this->artisan('generate:controller foo --test');
42 | $this->assertFileExists('app/Http/Controllers/FooController.php');
43 | $this->assertFileExists('tests/Feature/Controllers/FooControllerTest.php');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/EventCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:event InvoiceWasPaid');
11 | $this->assertFileExists('app/Events/InvoiceWasPaid.php');
12 |
13 | $this->artisan('generate:listener NotifyUserAboutPayment --event=InvoiceWasPaid');
14 | $this->assertFileExists('app/Listeners/NotifyUserAboutPayment.php');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/ExceptionCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:exception UserIsNotLoggedIn');
11 | $this->assertFileExists('app/Exceptions/UserIsNotLoggedIn.php');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/FactoryCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:factory Post');
11 | $this->assertFileExists('database/factories/PostFactory.php');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/FileCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:file test');
11 |
12 | $this->assertFileExists('resources/views/test.blade.php');
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/JobCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:job SendReminderEmail');
11 | $this->assertFileExists('app/Jobs/SendReminderEmail.php');
12 | }
13 |
14 | /** @test */
15 | public function generate_job_with_option_test()
16 | {
17 | $this->artisan('generate:job ProductPaid --test');
18 | $this->assertFileExists('app/Jobs/ProductPaid.php');
19 | $this->assertFileExists('tests/Unit/Jobs/ProductPaidTest.php');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/LivewireCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:livewire foo');
11 | $this->assertFileExists('app/Http/Livewire/Foo.php');
12 | $this->assertFileExists('resources/views/livewire/foo.blade.php');
13 |
14 | $this->artisan('generate:livewire Bar');
15 | $this->assertFileExists('app/Http/Livewire/Bar.php');
16 | $this->assertFileExists('resources/views/livewire/bar.blade.php');
17 |
18 | $this->artisan('generate:livewire FooBar');
19 | $this->assertFileExists('app/Http/Livewire/FooBar.php');
20 | $this->assertFileExists('resources/views/livewire/foo-bar.blade.php');
21 |
22 | $this->artisan('generate:livewire Foo/Bar');
23 | $this->assertFileExists('app/Http/Livewire/Foo/Bar.php');
24 | $this->assertFileExists('resources/views/livewire/foo/bar.blade.php');
25 |
26 | $this->artisan('generate:livewire folder.foo');
27 | $this->assertFileExists('app/Http/Livewire/Folder/Foo.php');
28 | $this->assertFileExists('resources/views/livewire/folder/foo.blade.php');
29 |
30 | $this->artisan('generate:livewire folder.foo-bar');
31 | $this->assertFileExists('app/Http/Livewire/Folder/FooBar.php');
32 | $this->assertFileExists('resources/views/livewire/folder/foo-bar.blade.php');
33 | }
34 |
35 | /** @test */
36 | public function generate_livewire_test_option()
37 | {
38 | $this->artisan('generate:livewire Foo --test');
39 | $this->assertFileExists('app/Http/Livewire/Foo.php');
40 | $this->assertFileExists('resources/views/livewire/foo.blade.php');
41 | $this->assertFileExists('tests/Feature/Livewire/FooTest.php');
42 | }
43 |
44 | /** @test */
45 | public function generate_livewire_request_option()
46 | {
47 | $this->artisan('generate:livewire Foo/Bar/Baz --request');
48 | $this->assertFileExists('app/Http/Livewire/Foo/Bar/Baz.php');
49 | $this->assertFileExists('resources/views/livewire/foo/bar/baz.blade.php');
50 | $this->assertFileExists('app/Http/Requests/Foo/Bar/BazRequest.php');
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/MiddlewareCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:middleware AuthenticateAdmin');
11 | $this->assertFileExists('app/Http/Middleware/AuthenticateAdmin.php');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/MigrationCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:migration create_users_table');
11 | $this->assertFileExists('app/Models/User.php');
12 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_users_table.php');
13 |
14 | $this->artisan('generate:migration create_user_comments_table');
15 | $this->assertFileExists('app/Models/UserComment.php');
16 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_user_comments_table.php');
17 | }
18 |
19 | /** @test */
20 | public function generate_migration_pivot()
21 | {
22 | $this->artisan('generate:migration create_tags_table');
23 | $this->artisan('generate:migration create_posts_table');
24 | $this->artisan('generate:migration:pivot tags posts')->expectsQuestion("Add Many To Many Relationship in 'Tag' and 'Post' Models? [yes|no]", 'yes')->assertExitCode(0);
25 |
26 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_post_tag_pivot_table.php');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/ModelCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:model test');
11 | $this->assertFileExists('app/Models/Test.php');
12 |
13 | $this->artisan('generate:model foo');
14 | $this->assertFileExists('app/Models/Foo.php');
15 |
16 | $this->artisan('generate:model foo.bar');
17 | $this->assertFileExists('app/Models/Bar.php');
18 |
19 | $this->artisan('generate:model plain --plain');
20 | $this->assertFileExists('app/Models/Plain.php');
21 |
22 | $this->artisan('generate:model foo --force');
23 | $this->assertFileExists('app/Models/Foo.php');
24 | }
25 |
26 | /** @test */
27 | public function generate_model_with_migration()
28 | {
29 | $this->artisan('generate:model foo --migration');
30 | $this->assertFileExists('app/Models/Foo.php');
31 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_foos_table.php');
32 |
33 | $this->artisan('generate:model UserComment --migration');
34 | $this->assertFileExists('app/Models/UserComment.php');
35 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_user_comments_table.php');
36 | }
37 |
38 | /** @test */
39 | public function generate_model_with_option_factory()
40 | {
41 | $this->artisan('generate:model Comment --factory');
42 | $this->assertFileExists('app/Models/Comment.php');
43 | $this->assertFileExists('database/factories/CommentFactory.php');
44 | }
45 |
46 | /** @test */
47 | public function generate_model_with_option_test()
48 | {
49 | $this->artisan('generate:model Post --test');
50 | $this->assertFileExists('app/Models/Post.php');
51 | $this->assertFileExists('tests/Unit/Models/PostTest.php');
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/NotificationCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:notification ContractUsSubmitted');
11 | $this->assertFileExists('app/Notifications/ContractUsSubmitted.php');
12 |
13 | $this->artisan('generate:notification Admin/UserRegistered');
14 | $this->assertFileExists('app/Notifications/Admin/UserRegistered.php');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/RepositoryCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:repository Post');
11 | $this->assertFileExists('app/Repositories/PostRepository.php');
12 |
13 | $this->artisan('generate:repository TagsRepository');
14 | $this->assertFileExists('app/Repositories/TagsRepository.php');
15 | }
16 |
17 | /** @test */
18 | public function generate_repository_with_option_test()
19 | {
20 | $this->artisan('generate:repository Foo --test');
21 | $this->assertFileExists('app/Repositories/FooRepository.php');
22 | $this->assertFileExists('tests/Unit/Repositories/FooRepositoryTest.php');
23 | }
24 |
25 | /** @test */
26 | public function generate_repository_with_contract_stub()
27 | {
28 | $this->artisan('generate:repository BookingRepository --contract');
29 | $this->assertFileExists('app/Repositories/BookingRepository.php');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/RequestCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:request PostStore');
11 | $this->assertFileExists('app/Http/Requests/PostStoreRequest.php');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/ResourceCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:resource post')
11 | ->expectsQuestion('Create a Post model?', true)
12 | ->expectsQuestion('Create crud views for the post resource?', true)
13 | ->expectsQuestion('Create a controller (PostsController) for the post resource?', true)
14 | ->expectsQuestion('Create a migration (create_posts_table) for the post resource?', true)
15 | ->expectsQuestion('Create a seeder (PostsTableSeeder) for the post resource?', true)
16 | ->expectsQuestion('Create a test (PostTest) for the post resource?', true)
17 | ->expectsQuestion('Create a factory (PostFactory) for the post resource?', true)
18 | ->expectsQuestion('Migrate the database?', false)
19 | ->expectsQuestion('Run \'composer dump-autoload\'?', false)
20 | ->assertExitCode(0);
21 |
22 | $this->assertFileExists('app/Models/Post.php');
23 | $this->assertFileExists('resources/views/post/create_edit.blade.php');
24 | $this->assertFileExists('resources/views/post/index.blade.php');
25 | $this->assertFileExists('resources/views/post/show.blade.php');
26 | $this->assertFileExists('app/Http/Controllers/PostsController.php');
27 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_posts_table.php');
28 | $this->assertFileExists('database/factories/PostFactory.php');
29 | $this->assertFileExists('database/seeders/PostsTableSeeder.php');
30 | // $this->assertFileExists('tests/Feature/PostTest.php');
31 | $this->assertFileExists('tests/Unit/PostTest.php');
32 | }
33 |
34 | /** @test */
35 | public function generate_resource_with_admin_controller_stub()
36 | {
37 | $this->artisan('generate:resource articles --controller=admin')
38 | ->expectsQuestion('Create a Article model?', true)
39 | ->expectsQuestion('Create crud views for the article resource?', true)
40 | ->expectsQuestion('Create a controller (ArticlesController) for the article resource?', true)
41 | ->expectsQuestion('Create a migration (create_articles_table) for the article resource?', true)
42 | ->expectsQuestion('Create a seeder (ArticlesTableSeeder) for the article resource?', true)
43 | ->expectsQuestion('Create a test (ArticleTest) for the article resource?', true)
44 | ->expectsQuestion('Create a factory (ArticleFactory) for the article resource?', true)
45 | ->expectsQuestion('Migrate the database?', false)
46 | ->expectsQuestion('Run \'composer dump-autoload\'?', false)
47 | ->assertExitCode(0);
48 |
49 | $this->assertFileExists('app/Models/Article.php');
50 | $this->assertFileExists('resources/views/articles/create_edit.blade.php');
51 | $this->assertFileExists('resources/views/articles/index.blade.php');
52 | $this->assertFileExists('resources/views/articles/show.blade.php');
53 | $this->assertFileExists('app/Http/Controllers/ArticlesController.php');
54 | $this->assertFileExists('database/migrations/'. date('Y_m_d_His') .'_create_articles_table.php');
55 | $this->assertFileExists('database/factories/ArticleFactory.php');
56 | $this->assertFileExists('database/seeders/ArticlesTableSeeder.php');
57 | // $this->assertFileExists('tests/Feature/ArticlesTest.php');
58 | $this->assertFileExists('tests/Unit/ArticleTest.php');
59 | }
60 |
61 | /** @test */
62 | public function generate_resource_with_bootstrap_4_stubs()
63 | {
64 | $this->artisan('generate:resource articles --view=b3')
65 | ->expectsQuestion('Create a Article model?', false)
66 | ->expectsQuestion('Create crud views for the article resource?', true)
67 | ->expectsQuestion('Create a controller (ArticlesController) for the article resource?', false)
68 | ->expectsQuestion('Create a migration (create_articles_table) for the article resource?', false)
69 | ->expectsQuestion('Create a seeder (ArticlesTableSeeder) for the article resource?', false)
70 | ->expectsQuestion('Create a test (ArticleTest) for the article resource?', false)
71 | ->expectsQuestion('Create a factory (ArticleFactory) for the article resource?', false)
72 | ->expectsQuestion('Migrate the database?', false)
73 | ->expectsQuestion('Run \'composer dump-autoload\'?', false)
74 | ->assertExitCode(0);
75 |
76 | $this->assertFileExists('resources/views/articles/create_edit.blade.php');
77 | $this->assertFileExists('resources/views/articles/index.blade.php');
78 | $this->assertFileExists('resources/views/articles/show.blade.php');
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/tests/SeederCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:seeder post');
11 | $this->assertFileExists('database/seeders/PostsTableSeeder.php');
12 |
13 | $this->artisan('generate:seeder UserTableSeeder');
14 | $this->assertFileExists('database/seeders/UsersTableSeeder.php');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | cleanOutputDirectory();
16 | }
17 |
18 | private function cleanOutputDirectory(): void
19 | {
20 | if (File::isDirectory('output')) {
21 | File::deleteDirectories('output');
22 | }
23 |
24 | //if (File::isDirectory('resources')) {
25 | // File::deleteDirectories('resources');
26 | //}
27 |
28 | if (File::isDirectory('app')) {
29 | File::deleteDirectories('app');
30 | }
31 |
32 | if (File::isDirectory('database')) {
33 | File::deleteDirectories('database');
34 | }
35 | }
36 |
37 | /**
38 | * Load package service provider.
39 | *
40 | * @param \Illuminate\Foundation\Application $app
41 | * @return array
42 | */
43 | protected function getPackageProviders($app): array
44 | {
45 | return [
46 | GeneratorsServiceProvider::class
47 | ];
48 | }
49 |
50 | /**
51 | * Resolve application core configuration implementation.
52 | *
53 | * @param \Illuminate\Foundation\Application $app
54 | *
55 | * @return void
56 | */
57 | protected function resolveApplicationConfiguration($app): void
58 | {
59 | parent::resolveApplicationConfiguration($app);
60 |
61 | $path = __DIR__ . '/../resources/stubs/';
62 |
63 | $app['config']->set('generators.stubs.example', "{$path}example.stub");
64 | $app['config']->set('generators.stubs.model', "{$path}model.stub");
65 | $app['config']->set('generators.stubs.model_plain', "{$path}model.plain.stub");
66 | $app['config']->set('generators.stubs.migration', "{$path}migration.stub");
67 | $app['config']->set('generators.stubs.migration_plain', "{$path}migration.plain.stub");
68 | $app['config']->set('generators.stubs.controller', "{$path}controller.stub");
69 | $app['config']->set('generators.stubs.controller_plain', "{$path}controller.plain.stub");
70 | $app['config']->set('generators.stubs.controller_admin', "{$path}controller_admin.stub");
71 | $app['config']->set('generators.stubs.controller_repository', "{$path}controller_repository.stub");
72 | $app['config']->set('generators.stubs.request', "{$path}request.stub");
73 | $app['config']->set('generators.stubs.pivot', "{$path}pivot.stub");
74 | $app['config']->set('generators.stubs.seeder', "{$path}seeder.stub");
75 | $app['config']->set('generators.stubs.seeder_plain', "{$path}seeder.plain.stub");
76 | $app['config']->set('generators.stubs.view', "{$path}view.stub");
77 | $app['config']->set('generators.stubs.view_index', "{$path}view.index.stub");
78 | $app['config']->set('generators.stubs.view_indexb4', "{$path}view.index.b4.stub");
79 | $app['config']->set('generators.stubs.view_show', "{$path}view.show.stub");
80 | $app['config']->set('generators.stubs.view_showb4', "{$path}view.show.b4.stub");
81 | $app['config']->set('generators.stubs.view_create_edit', "{$path}view.create_edit.stub");
82 | $app['config']->set('generators.stubs.view_create_editb4', "{$path}view.create_edit.b4.stub");
83 | $app['config']->set('generators.stubs.schema_create', "{$path}schema_create.stub");
84 | $app['config']->set('generators.stubs.schema_change', "{$path}schema_change.stub");
85 | $app['config']->set('generators.stubs.notification', "{$path}notification.stub");
86 | $app['config']->set('generators.stubs.event', "{$path}event.stub");
87 | $app['config']->set('generators.stubs.listener', "{$path}listener.stub");
88 | $app['config']->set('generators.stubs.many_many_relationship', "{$path}many_many_relationship.stub");
89 | $app['config']->set('generators.stubs.trait', "{$path}trait.stub");
90 | $app['config']->set('generators.stubs.job', "{$path}job.stub");
91 | $app['config']->set('generators.stubs.console', "{$path}console.stub");
92 | $app['config']->set('generators.stubs.middleware', "{$path}middleware.stub");
93 | $app['config']->set('generators.stubs.repository', "{$path}repository.stub");
94 | $app['config']->set('generators.stubs.repository_contract', "{$path}repository.contract.stub");
95 | $app['config']->set('generators.stubs.contract', "{$path}contract.stub");
96 | $app['config']->set('generators.stubs.factory', "{$path}factory.stub");
97 | $app['config']->set('generators.stubs.exception', "{$path}exception.stub");
98 | $app['config']->set('generators.stubs.test', "{$path}test.stub");
99 | $app['config']->set('generators.stubs.livewire', "{$path}livewire.stub");
100 | $app['config']->set('generators.stubs.livewire_view', "{$path}livewire.view.stub");
101 | $app['config']->set('generators.stubs.component', "{$path}component.stub");
102 | $app['config']->set('generators.stubs.component_view', "{$path}component.view.stub");
103 |
104 | // $path = '../tests/output/';
105 | // dd($app['config']->get('generators'));
106 | //$app['config']->set('generators.settings.view.path', "{$path}resources/views/");
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/tests/TestCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:test Controllers/UsersController');
11 | $this->assertFileExists('tests/Feature/Controllers/UsersControllerTest.php');
12 |
13 | $this->artisan('generate:test Models/Post --unit');
14 | $this->assertFileExists('tests/Unit/Models/PostTest.php');
15 |
16 | $this->artisan('generate:test Traits/InvoiceTest --unit');
17 | $this->assertFileExists('tests/Unit/Traits/InvoiceTest.php');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/TraitCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:trait Traits/UserHelper');
11 | $this->assertFileExists('app/Traits/UserHelper.php');
12 |
13 | $this->artisan('generate:trait Http/Controllers/Traits/PhotoHelper');
14 | $this->assertFileExists('app/Http/Controllers/Traits/PhotoHelper.php');
15 | }
16 |
17 | /** @test */
18 | public function generate_trait_with_option_test()
19 | {
20 | $this->artisan('generate:trait Traits/RoleHelper --test');
21 | $this->assertFileExists('app/Traits/RoleHelper.php');
22 | $this->assertFileExists('tests/Unit/Traits/RoleHelperTest.php');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/ViewCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('generate:view view');
11 | $this->assertFileExists('resources/views/view.blade.php');
12 |
13 | $this->artisan('generate:view foo.bar');
14 | $this->assertFileExists('resources/views/foo/bar.blade.php');
15 |
16 | $this->artisan('generate:view foo --stub=view_show');
17 | $this->assertFileExists('resources/views/foo.blade.php');
18 |
19 | $this->artisan('generate:view foo --name=foo_bar');
20 | $this->assertFileExists('resources/views/foo/foo_bar.blade.php');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/todo.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpocallaghan/generators/b627bf48420f5ed9e2375defdb5421c34b121029/todo.md
--------------------------------------------------------------------------------