├── .github
├── dependabot.yml
└── workflows
│ ├── dependabot-auto-merge.yml
│ ├── fix-php-code-style-issues.yml
│ ├── phpstan.yml
│ └── run-tests.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── composer.json
├── composer.lock
├── img
└── banner.png
├── phpstan-baseline.neon
├── phpstan.neon.dist
├── phpunit.xml.dist
├── phpunit.xml.dist.bak
├── src
├── Console
│ └── MakePivotCommand.php
└── PivotTableGeneratorServiceProvider.php
├── stubs
└── pivot_migration.stub
└── tests
├── Pest.php
├── PivotTableGeneratorTest.php
└── TestCase.php
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3 |
4 | version: 2
5 | updates:
6 |
7 | - package-ecosystem: "github-actions"
8 | directory: "/"
9 | schedule:
10 | interval: "weekly"
11 | labels:
12 | - "dependencies"
13 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot-auto-merge.yml:
--------------------------------------------------------------------------------
1 | name: dependabot-auto-merge
2 | on: pull_request_target
3 |
4 | permissions:
5 | pull-requests: write
6 | contents: write
7 |
8 | jobs:
9 | dependabot:
10 | runs-on: ubuntu-latest
11 | if: ${{ github.actor == 'dependabot[bot]' }}
12 | steps:
13 |
14 | - name: Dependabot metadata
15 | id: metadata
16 | uses: dependabot/fetch-metadata@v1.6.0
17 | with:
18 | github-token: "${{ secrets.GITHUB_TOKEN }}"
19 |
20 | - name: Auto-merge Dependabot PRs for semver-minor updates
21 | if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor'}}
22 | run: gh pr merge --auto --merge "$PR_URL"
23 | env:
24 | PR_URL: ${{github.event.pull_request.html_url}}
25 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
26 |
27 | - name: Auto-merge Dependabot PRs for semver-patch updates
28 | if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
29 | run: gh pr merge --auto --merge "$PR_URL"
30 | env:
31 | PR_URL: ${{github.event.pull_request.html_url}}
32 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
33 |
--------------------------------------------------------------------------------
/.github/workflows/fix-php-code-style-issues.yml:
--------------------------------------------------------------------------------
1 | name: Fix PHP code style issues
2 |
3 | on:
4 | push:
5 | paths:
6 | - '**.php'
7 |
8 | permissions:
9 | contents: write
10 |
11 | jobs:
12 | php-code-styling:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout code
17 | uses: actions/checkout@v4
18 | with:
19 | ref: ${{ github.head_ref }}
20 |
21 | - name: Fix PHP code style issues
22 | uses: aglipanci/laravel-pint-action@2.4
23 |
24 | - name: Commit changes
25 | uses: stefanzweifel/git-auto-commit-action@v5
26 | with:
27 | commit_message: Fix styling
28 |
--------------------------------------------------------------------------------
/.github/workflows/phpstan.yml:
--------------------------------------------------------------------------------
1 | name: PHPStan
2 |
3 | on:
4 | push:
5 | paths:
6 | - '**.php'
7 | - 'phpstan.neon.dist'
8 |
9 | jobs:
10 | phpstan:
11 | name: phpstan
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 |
16 | - name: Setup PHP
17 | uses: shivammathur/setup-php@v2
18 | with:
19 | php-version: '8.1'
20 | coverage: none
21 |
22 | - name: Install composer dependencies
23 | uses: ramsey/composer-install@v2
24 |
25 | - name: Run PHPStan
26 | run: ./vendor/bin/phpstan --error-format=github
27 |
--------------------------------------------------------------------------------
/.github/workflows/run-tests.yml:
--------------------------------------------------------------------------------
1 | name: run-tests
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 |
9 | jobs:
10 | test:
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | fail-fast: true
14 | matrix:
15 | os: [ubuntu-latest, windows-latest]
16 | php: [8.2, 8.1]
17 | laravel: [10.*]
18 | stability: [prefer-lowest, prefer-stable]
19 | include:
20 | - laravel: 10.*
21 | testbench: 8.*
22 | carbon: ^2.63
23 |
24 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
25 |
26 | steps:
27 | - name: Checkout code
28 | uses: actions/checkout@v4
29 |
30 | - name: Setup PHP
31 | uses: shivammathur/setup-php@v2
32 | with:
33 | php-version: ${{ matrix.php }}
34 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
35 | coverage: none
36 |
37 | - name: Setup problem matchers
38 | run: |
39 | echo "::add-matcher::${{ runner.tool_cache }}/php.json"
40 | echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
41 |
42 | - name: Install dependencies
43 | run: |
44 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" --no-interaction --no-update
45 | composer update --${{ matrix.stability }} --prefer-dist --no-interaction
46 |
47 | - name: List Installed Dependencies
48 | run: composer show -D
49 |
50 | - name: Execute tests
51 | run: vendor/bin/pest
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .phpunit.cache
3 | build
4 | composer.lock
5 | coverage
6 | docs
7 | phpunit.xml
8 | phpstan.neon
9 | testbench.yaml
10 | vendor
11 | node_modules
12 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Tim Wassenburg
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator)
4 | [](https://github.com/timwassenburg/laravel-pivot-table-generator/actions?query=workflow%3Arun-tests+branch%3Amaster)
5 | [](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator)
6 | [](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator)
7 |
8 |
9 |
10 | ## Table of Contents
11 |
12 | - Installation
13 | -
14 | Usage
15 |
16 | - Testing
17 | - More generator packages
18 | - Contributing
19 | - License
20 |
21 |
22 | ## Installation
23 | Install the package with composer.
24 | ```bash
25 | composer require timwassenburg/laravel-pivot-table-generator --dev
26 | ```
27 |
28 | ## Usage
29 | Run the following command on the command-line to generate a new migration for the pivot table.
30 | ```bash
31 | php artisan make:pivot {first_table_name} {second_table_name}
32 | ```
33 |
34 | The command will create a new migration in ```database/migrations```. Run the migrations to create the table.
35 | ```bash
36 | php artisan migrate
37 | ```
38 |
39 | ## Testing
40 |
41 | Run the tests with:
42 |
43 | ```bash
44 | composer test
45 | ```
46 |
47 | ## More generator packages
48 |
49 | Looking for more ways to speed up your workflow? Make sure to check out these packages.
50 |
51 | - [Laravel Action Generator](https://github.com/timwassenburg/laravel-action-generator)
52 | - [Laravel Pivot Table Generator](https://github.com/timwassenburg/laravel-pivot-table-generator)
53 | - [Laravel Repository Generator](https://github.com/timwassenburg/laravel-repository-generator)
54 | - [Laravel Service Generator](https://github.com/timwassenburg/laravel-service-generator)
55 | - [Laravel Trait Generator](https://github.com/timwassenburg/laravel-trait-generator)
56 |
57 | The packages mentioned above are part of [Laravel Artisan Extender](https://github.com/timwassenburg/laravel-artisan-extender).
58 |
59 | ## Contributing
60 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
61 |
62 | If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
63 | Don't forget to give the project a star! Thanks again!
64 |
65 | 1. Fork the Project
66 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
67 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
68 | 4. Push to the Branch (`git push origin feature/AmazingFeature`)
69 | 5. Open a Pull Request
70 |
71 | ## License
72 |
73 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
74 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "timwassenburg/laravel-pivot-table-generator",
3 | "description": "Quickly generate pivot tables for your projects",
4 | "keywords": ["generator", "php", "cli", "laravel", "artisan", "pivot", "migrations"],
5 | "homepage": "https://github.com/timwassenburg/laravel-pivot-table-generator",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Tim Wassenburg"
10 | }
11 | ],
12 | "autoload": {
13 | "psr-4": {
14 | "TimWassenburg\\PivotTableGenerator\\": "src/"
15 | }
16 | },
17 | "autoload-dev": {
18 | "psr-4": {
19 | "TimWassenburg\\PivotTableGenerator\\Tests\\": "tests/"
20 | }
21 | },
22 | "scripts": {
23 | "post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi",
24 | "analyse": "vendor/bin/phpstan analyse",
25 | "test": "vendor/bin/pest",
26 | "test-coverage": "vendor/bin/pest --coverage",
27 | "format": "vendor/bin/pint"
28 | },
29 | "extra": {
30 | "laravel": {
31 | "providers": [
32 | "TimWassenburg\\PivotTableGenerator\\PivotTableGeneratorServiceProvider"
33 | ]
34 | }
35 | },
36 | "require-dev": {
37 | "pestphp/pest": "^2.5",
38 | "orchestra/testbench": "^8.5",
39 | "laravel/pint": "^1.10",
40 | "nunomaduro/larastan": "^2.0"
41 | },
42 | "config": {
43 | "allow-plugins": {
44 | "pestphp/pest-plugin": true
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/img/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timwassenburg/laravel-pivot-table-generator/325bec92f49d09839206fdb578079b04add5d8fb/img/banner.png
--------------------------------------------------------------------------------
/phpstan-baseline.neon:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timwassenburg/laravel-pivot-table-generator/325bec92f49d09839206fdb578079b04add5d8fb/phpstan-baseline.neon
--------------------------------------------------------------------------------
/phpstan.neon.dist:
--------------------------------------------------------------------------------
1 | includes:
2 | - phpstan-baseline.neon
3 |
4 | parameters:
5 | level: 4
6 | paths:
7 | - src
8 | tmpDir: build/phpstan
9 | checkMissingIterableValueType: false
10 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/phpunit.xml.dist.bak:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 | tests
21 |
22 |
23 |
24 |
25 | ./src
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/Console/MakePivotCommand.php:
--------------------------------------------------------------------------------
1 | files->get($this->getStub());
43 |
44 | return $this->populateStub($stub);
45 | }
46 |
47 | /**
48 | * Replace the namespace for the given stub.
49 | */
50 | protected function populateStub(string $stub): string
51 | {
52 | [$firstTable, $secondTable] = $this->getSortedInput();
53 |
54 | $searches = [
55 | [
56 | '{{ first_table_name }}',
57 | '{{ second_table_name }}',
58 | '{{ class }}',
59 | '{{ pivot_table }}',
60 | ],
61 | ];
62 |
63 | foreach ($searches as $search) {
64 | $stub = str_replace(
65 | $search,
66 | [
67 | $firstTable,
68 | $secondTable,
69 | $this->getClassName(),
70 | $this->getNameInput(),
71 | ],
72 | $stub
73 | );
74 | }
75 |
76 | return $stub;
77 | }
78 |
79 | public function getClassName(): string
80 | {
81 | $name = Str::studly($this->getNameInput());
82 |
83 | return "Create{$name}Table";
84 | }
85 |
86 | protected function getSortedInput(): array
87 | {
88 | $inputValues = [
89 | $this->getSingularInput('first_table_name'),
90 | $this->getSingularInput('second_table_name'),
91 | ];
92 | sort($inputValues);
93 |
94 | return $inputValues;
95 | }
96 |
97 | /**
98 | * Get the desired class name from the input.
99 | */
100 | protected function getNameInput(): string
101 | {
102 | $sortedInput = $this->getSortedInput();
103 |
104 | return implode('_', $sortedInput);
105 | }
106 |
107 | protected function getSingularInput(string $name): string
108 | {
109 | return Str::lower(Str::singular(trim($this->argument($name))));
110 | }
111 |
112 | /**
113 | * Get the stub file for the generator.
114 | */
115 | protected function getStub(): string
116 | {
117 | return __DIR__.'/../../stubs/pivot_migration.stub';
118 | }
119 |
120 | /**
121 | * Get the default namespace for the class.
122 | *
123 | * @param string $rootNamespace
124 | */
125 | protected function getDefaultNamespace($rootNamespace): string
126 | {
127 | return $rootNamespace.'/../database/migrations';
128 | }
129 |
130 | /**
131 | * Get the console command arguments.
132 | */
133 | protected function getArguments(): array
134 | {
135 | return [
136 | ['first_table_name', InputArgument::REQUIRED, 'The name of the first table'],
137 | ['second_table_name', InputArgument::REQUIRED, 'The name of the second table'],
138 | ];
139 | }
140 |
141 | /**
142 | * Get the destination class path.
143 | *
144 | * @param string $name
145 | */
146 | protected function getPath($name): string
147 | {
148 | $filename = now()->format('Y_m_d_his').'_create_'.$this->getNameInput().'_table.php';
149 |
150 | return database_path('migrations/'.$filename);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/PivotTableGeneratorServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->runningInConsole()) {
13 | $this->commands([MakePivotCommand::class]);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/stubs/pivot_migration.stub:
--------------------------------------------------------------------------------
1 | foreignId('{{ first_table_name }}_id')->onDelete('cascade');
18 | $table->foreignId('{{ second_table_name }}_id')->onDelete('cascade');
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | *
25 | * @return void
26 | */
27 | public function down()
28 | {
29 | Schema::dropIfExists('{{ pivot_table }}');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Pest.php:
--------------------------------------------------------------------------------
1 | in(__DIR__);
6 |
--------------------------------------------------------------------------------
/tests/PivotTableGeneratorTest.php:
--------------------------------------------------------------------------------
1 | artisan('make:pivot Table1 Table2')
5 | ->assertExitCode(0);
6 | });
7 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | 'TimWassenburg\\PivotTableGenerator\\Database\\Factories\\'.class_basename($modelName).'Factory'
17 | );
18 | }
19 |
20 | protected function getPackageProviders($app)
21 | {
22 | return [
23 | PivotTableGeneratorServiceProvider::class,
24 | ];
25 | }
26 |
27 | public function getEnvironmentSetUp($app)
28 | {
29 | config()->set('database.default', 'testing');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------