2026-05-26 08:14:29 +02:00
< ? php
use Illuminate\Database\Migrations\Migration ;
use Illuminate\Database\Schema\Blueprint ;
use Illuminate\Support\Facades\Schema ;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up () : void
{
$teams = config ( 'permission.teams' );
$tableNames = config ( 'permission.table_names' );
$columnNames = config ( 'permission.column_names' );
$pivotRole = $columnNames [ 'role_pivot_key' ] ? ? 'role_id' ;
$pivotPermission = $columnNames [ 'permission_pivot_key' ] ? ? 'permission_id' ;
throw_if ( empty ( $tableNames ), 'Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.' );
throw_if ( $teams && empty ( $columnNames [ 'team_foreign_key' ] ? ? null ), 'Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.' );
/**
* See `docs/prerequisites.md` for suggested lengths on 'name' and 'guard_name' if "1071 Specified key was too long" errors are encountered.
*/
2026-06-17 19:13:40 +02:00
if ( ! Schema :: hasTable ( $tableNames [ 'permissions' ])) {
Schema :: create ( $tableNames [ 'permissions' ], static function ( Blueprint $table ) {
$table -> id (); // permission id
$table -> string ( 'name' );
$table -> string ( 'guard_name' );
$table -> timestamps ();
$table -> unique ([ 'name' , 'guard_name' ]);
});
}
2026-05-26 08:14:29 +02:00
/**
* See `docs/prerequisites.md` for suggested lengths on 'name' and 'guard_name' if "1071 Specified key was too long" errors are encountered.
*/
2026-06-17 19:13:40 +02:00
if ( ! Schema :: hasTable ( $tableNames [ 'roles' ])) {
Schema :: create ( $tableNames [ 'roles' ], static function ( Blueprint $table ) use ( $teams , $columnNames ) {
$table -> id (); // role id
if ( $teams || config ( 'permission.testing' )) { // permission.testing is a fix for sqlite testing
2026-05-26 08:14:29 +02:00
$table -> unsignedBigInteger ( $columnNames [ 'team_foreign_key' ]) -> nullable ();
$table -> index ( $columnNames [ 'team_foreign_key' ], 'roles_team_foreign_key_index' );
2026-06-17 19:13:40 +02:00
}
$table -> string ( 'name' );
$table -> string ( 'guard_name' );
$table -> timestamps ();
if ( $teams || config ( 'permission.testing' )) {
2026-05-26 08:14:29 +02:00
$table -> unique ([ $columnNames [ 'team_foreign_key' ], 'name' , 'guard_name' ]);
2026-06-17 19:13:40 +02:00
} else {
2026-05-26 08:14:29 +02:00
$table -> unique ([ 'name' , 'guard_name' ]);
2026-06-17 19:13:40 +02:00
}
});
}
if ( ! Schema :: hasTable ( $tableNames [ 'model_has_permissions' ])) {
Schema :: create ( $tableNames [ 'model_has_permissions' ], static function ( Blueprint $table ) use ( $tableNames , $columnNames , $pivotPermission , $teams ) {
$table -> unsignedBigInteger ( $pivotPermission );
$table -> string ( 'model_type' );
$table -> unsignedBigInteger ( $columnNames [ 'model_morph_key' ]);
$table -> index ([ $columnNames [ 'model_morph_key' ], 'model_type' ], 'model_has_permissions_model_id_model_type_index' );
$table -> foreign ( $pivotPermission )
2026-05-26 08:14:29 +02:00
-> references ( 'id' ) // permission id
-> on ( $tableNames [ 'permissions' ])
-> cascadeOnDelete ();
2026-06-17 19:13:40 +02:00
if ( $teams ) {
2026-05-26 08:14:29 +02:00
$table -> unsignedBigInteger ( $columnNames [ 'team_foreign_key' ]);
$table -> index ( $columnNames [ 'team_foreign_key' ], 'model_has_permissions_team_foreign_key_index' );
2026-06-17 19:13:40 +02:00
2026-05-26 08:14:29 +02:00
$table -> primary ([ $columnNames [ 'team_foreign_key' ], $pivotPermission , $columnNames [ 'model_morph_key' ], 'model_type' ],
'model_has_permissions_permission_model_type_primary' );
2026-06-17 19:13:40 +02:00
} else {
2026-05-26 08:14:29 +02:00
$table -> primary ([ $pivotPermission , $columnNames [ 'model_morph_key' ], 'model_type' ],
'model_has_permissions_permission_model_type_primary' );
2026-06-17 19:13:40 +02:00
}
});
}
if ( ! Schema :: hasTable ( $tableNames [ 'model_has_roles' ])) {
Schema :: create ( $tableNames [ 'model_has_roles' ], static function ( Blueprint $table ) use ( $tableNames , $columnNames , $pivotRole , $teams ) {
$table -> unsignedBigInteger ( $pivotRole );
$table -> string ( 'model_type' );
$table -> unsignedBigInteger ( $columnNames [ 'model_morph_key' ]);
$table -> index ([ $columnNames [ 'model_morph_key' ], 'model_type' ], 'model_has_roles_model_id_model_type_index' );
$table -> foreign ( $pivotRole )
2026-05-26 08:14:29 +02:00
-> references ( 'id' ) // role id
-> on ( $tableNames [ 'roles' ])
-> cascadeOnDelete ();
2026-06-17 19:13:40 +02:00
if ( $teams ) {
2026-05-26 08:14:29 +02:00
$table -> unsignedBigInteger ( $columnNames [ 'team_foreign_key' ]);
$table -> index ( $columnNames [ 'team_foreign_key' ], 'model_has_roles_team_foreign_key_index' );
2026-06-17 19:13:40 +02:00
2026-05-26 08:14:29 +02:00
$table -> primary ([ $columnNames [ 'team_foreign_key' ], $pivotRole , $columnNames [ 'model_morph_key' ], 'model_type' ],
'model_has_roles_role_model_type_primary' );
2026-06-17 19:13:40 +02:00
} else {
2026-05-26 08:14:29 +02:00
$table -> primary ([ $pivotRole , $columnNames [ 'model_morph_key' ], 'model_type' ],
'model_has_roles_role_model_type_primary' );
2026-06-17 19:13:40 +02:00
}
});
}
if ( ! Schema :: hasTable ( $tableNames [ 'role_has_permissions' ])) {
Schema :: create ( $tableNames [ 'role_has_permissions' ], static function ( Blueprint $table ) use ( $tableNames , $pivotRole , $pivotPermission ) {
$table -> unsignedBigInteger ( $pivotPermission );
$table -> unsignedBigInteger ( $pivotRole );
$table -> foreign ( $pivotPermission )
2026-05-26 08:14:29 +02:00
-> references ( 'id' ) // permission id
-> on ( $tableNames [ 'permissions' ])
-> cascadeOnDelete ();
2026-06-17 19:13:40 +02:00
$table -> foreign ( $pivotRole )
2026-05-26 08:14:29 +02:00
-> references ( 'id' ) // role id
-> on ( $tableNames [ 'roles' ])
-> cascadeOnDelete ();
2026-06-17 19:13:40 +02:00
$table -> primary ([ $pivotPermission , $pivotRole ], 'role_has_permissions_permission_id_role_id_primary' );
});
}
2026-05-26 08:14:29 +02:00
app ( 'cache' )
-> store ( config ( 'permission.cache.store' ) != 'default' ? config ( 'permission.cache.store' ) : null )
-> forget ( config ( 'permission.cache.key' ));
}
/**
* Reverse the migrations.
*/
public function down () : void
{
$tableNames = config ( 'permission.table_names' );
throw_if ( empty ( $tableNames ), 'Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.' );
Schema :: dropIfExists ( $tableNames [ 'role_has_permissions' ]);
Schema :: dropIfExists ( $tableNames [ 'model_has_roles' ]);
Schema :: dropIfExists ( $tableNames [ 'model_has_permissions' ]);
Schema :: dropIfExists ( $tableNames [ 'roles' ]);
Schema :: dropIfExists ( $tableNames [ 'permissions' ]);
}
};