skip to Main Content

I’m creating a package and want to override the Migrate command but cannot seem to figure out how. It seems like Laravel itself is getting a higher priority over my ServiceProvider, is there a way to gain priority in the override and get my custom class in there via a package?

2

Answers


  1. Chosen as BEST ANSWER

    I found out why the replace wasn't working, the original service provider is deferred, meaning it's register and boot methods get called just before the MigrateCommand class is needed. When I deferred my service provider the same way it started to work!

    class MigrateServiceProvider extends ServiceProvider implements DeferrableProvider
    {
        public function register(): void
        {
            $this->app->scoped(Migrator::class, function(Application $app) {
                return $app->make('migrator');
            });
        }
    
        public function boot(): void
        {
            if ($this->app->runningInConsole()) {
                $this->commands([
                    NewMigrateCommand::class
                ]);
            }
        }
    
        public function provides(): array
        {
            return [NewMigrateCommand::class, Migrator::class];
        }
    }
    

  2. I tried to use a ServiceProvider‘s register() method to bind a custom implementation of IlluminateDatabaseMigrationsMigrator but it didn’t work.

    Although this is not pretty, I suppose you could use composer to autoload your custom implementation of whatever classes you need to override.

    For example, let’s say you want to override IlluminateDatabaseMigrationsMigrator.

    Write a new implementation of this class and save somewhere… for example in app/Overrides/Illuminate/Database/Migrations/Migrator.php.

    Inside this file, override the vendor class keeping the vendor namespace.

    // app/Overrides/Illuminate/Database/Migrations/Migrator.php
    namespace Illuminate/Database/Migrations;
    
    class Migrator
    {
        ....
    }
    

    Then, in your composer.json file, you need to explicitly state you want THIS class to be autoloaded instead of laravel’s, and also exclude laravel’s own class from the autoloading.

    "autoload": {
        ...
        "exclude-from-classmap": ["vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php"],
        "files": ["app/Overrides/Illuminate/Database/Migrations/Migrator.php"]
        ...
    },
    

    And finally, run composer dumpautoload. And run it again every time you add a new package with composer require.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search