├── .php-cs-fixer.php ├── LICENSE.md ├── composer.json ├── src ├── Commands │ └── PivotMakeCommand.php └── MakePivotServiceProvider.php └── stubs └── pivot.stub /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | in(__DIR__ . DIRECTORY_SEPARATOR . 'tests') 5 | ->in(__DIR__ . DIRECTORY_SEPARATOR . 'src') 6 | ->append(['.php_cs']); 7 | 8 | $rules = [ 9 | '@Symfony' => true, 10 | 'phpdoc_no_empty_return' => false, 11 | 'array_syntax' => ['syntax' => 'short'], 12 | 'yoda_style' => false, 13 | 'binary_operator_spaces' => [ 14 | 'operators' => [ 15 | '=>' => 'align', 16 | '=' => 'align', 17 | ], 18 | ], 19 | 'concat_space' => ['spacing' => 'one'], 20 | 'not_operator_with_space' => false, 21 | ]; 22 | 23 | $rules['increment_style'] = ['style' => 'post']; 24 | 25 | return (new PhpCsFixer\Config) 26 | ->setUsingCache(true) 27 | ->setRules($rules) 28 | ->setFinder($finder); 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Félix Dorn 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 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "felixdorn/laravel-make-pivot-table", 3 | "description": "An artisan command to create a pivot table with Laravel.", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Félix Dorn", 8 | "email": "github@felixdorn.fr" 9 | } 10 | ], 11 | "require": { 12 | "php": "^8" 13 | }, 14 | "require-dev": { 15 | "pestphp/pest": "^v1", 16 | "orchestra/testbench": "^v6.17.1", 17 | "friendsofphp/php-cs-fixer": "^v3.0.0", 18 | "phpstan/phpstan": "^1", 19 | "symfony/var-dumper": "^5.2.0" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Felix\\MakePivotTable\\": "src/" 24 | } 25 | }, 26 | "autoload-dev": { 27 | "psr-4": { 28 | "Felix\\MakePivotTable\\Tests\\": "tests/" 29 | } 30 | }, 31 | "minimum-stability": "dev", 32 | "prefer-stable": true, 33 | "config": { 34 | "sort-packages": true, 35 | "preferred-install": "dist" 36 | }, 37 | "scripts": { 38 | "lint": "php-cs-fixer fix -v", 39 | "test:lint": "php-cs-fixer fix -v --dry-run", 40 | "test:types": "phpstan analyse --ansi --memory-limit=-1", 41 | "test:unit": "pest --colors=always", 42 | "test": [ 43 | "@test:lint", 44 | "@test:types", 45 | "@test:unit" 46 | ] 47 | }, 48 | "extra": { 49 | "laravel": { 50 | "providers": [ 51 | "Felix\\MakePivotTable\\MakePivotServiceProvider" 52 | ] 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Commands/PivotMakeCommand.php: -------------------------------------------------------------------------------- 1 | files->get($this->getStub()); 20 | 21 | $stub = str_replace('{{pivotTableName}}', $this->getPivotTableName(), $stub); 22 | $stub = str_replace('{{class}}', $this->getClassName(), $stub); 23 | 24 | return str_replace( 25 | ['{{columnOne}}', '{{columnTwo}}', '{{tableOne}}', '{{tableTwo}}'], 26 | array_merge( 27 | $this->getSortedSingularTableNames(), 28 | $this->getSortedTableNames() 29 | ), 30 | $stub 31 | ); 32 | } 33 | 34 | protected function getStub(): string 35 | { 36 | return __DIR__ . '/../../stubs/pivot.stub'; 37 | } 38 | 39 | private function getPivotTableName(): string 40 | { 41 | return implode('_', $this->getSortedSingularTableNames()); 42 | } 43 | 44 | protected function getSortedSingularTableNames(): array 45 | { 46 | $tables = array_map(fn (string $table) => Str::singular($table), $this->getTableNamesFromInput()); 47 | 48 | sort($tables); 49 | 50 | return $tables; 51 | } 52 | 53 | protected function getTableNamesFromInput(): array 54 | { 55 | return [ 56 | /* @phpstan-ignore-next-line */ 57 | Str::plural(strtolower($this->argument('first_table'))), 58 | /* @phpstan-ignore-next-line */ 59 | Str::plural(strtolower($this->argument('second_table'))), 60 | ]; 61 | } 62 | 63 | protected function getClassName(): string 64 | { 65 | $name = implode('', array_map('ucwords', $this->getSortedSingularTableNames())); 66 | 67 | $name = preg_replace_callback('/(_)([a-z])/', function ($matches) { 68 | return Str::studly($matches[0]); 69 | }, $name); 70 | 71 | return "Create{$name}PivotTable"; 72 | } 73 | 74 | protected function getSortedTableNames(): array 75 | { 76 | $tables = $this->getTableNamesFromInput(); 77 | 78 | sort($tables); 79 | 80 | return $tables; 81 | } 82 | 83 | /* @phpstan-ignore-next-line */ 84 | protected function getNameInput() 85 | { 86 | } 87 | 88 | protected function getPath($name = null) 89 | { 90 | return base_path() . '/database/migrations/' . date('Y_m_d_His') . 91 | '_create_' . $this->getPivotTableName() . '_pivot_table.php'; 92 | } 93 | 94 | protected function getArguments(): array 95 | { 96 | return [ 97 | ['first_table', InputArgument::REQUIRED, 'The name of the first table.'], 98 | ['second_table', InputArgument::REQUIRED, 'The name of the second table.'], 99 | ]; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/MakePivotServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton('command.felix.make.pivot', function ($app) { 13 | return $app[PivotMakeCommand::class]; 14 | }); 15 | 16 | $this->commands('command.felix.make.pivot'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /stubs/pivot.stub: -------------------------------------------------------------------------------- 1 | foreignId('{{columnOne}}_id')->references('id')->on('{{tableOne}}')->cascadeOnDelete(); 12 | $table->foreignId('{{columnTwo}}_id')->references('id')->on('{{tableTwo}}')->cascadeOnDelete(); 13 | }); 14 | } 15 | 16 | public function down() 17 | { 18 | Schema::dropIfExists('{{pivotTableName}}'); 19 | } 20 | } 21 | --------------------------------------------------------------------------------