├── .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 | Logo 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/timwassenburg/laravel-pivot-table-generator.svg?style=flat-square)](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator) 4 | [![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/timwassenburg/laravel-pivot-table-generator/run-tests.yml?branch=master&label=tests&style=flat-square)](https://github.com/timwassenburg/laravel-pivot-table-generator/actions?query=workflow%3Arun-tests+branch%3Amaster) 5 | [![Total Downloads](https://img.shields.io/packagist/dt/timwassenburg/laravel-pivot-table-generator.svg?style=flat-square)](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator) 6 | [![License](https://img.shields.io/packagist/l/timwassenburg/laravel-pivot-table-generator)](https://packagist.org/packages/timwassenburg/laravel-pivot-table-generator) 7 | 8 |
9 | 10 | ## Table of Contents 11 |
    12 |
  1. Installation
  2. 13 |
  3. 14 | Usage 15 |
  4. 16 |
  5. Testing
  6. 17 |
  7. More generator packages
  8. 18 |
  9. Contributing
  10. 19 |
  11. License
  12. 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 | --------------------------------------------------------------------------------