2
votes

Without knowing how Laravel facades work, based on my PHP knowledge, I tried to extend Storage facade to add some new functionalities.

I have this code:

class MyStorageFacade extends Facade {
    /**
     * Get the binding in the IoC container
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'MyStorage'; // the IoC binding.
    }
}

While booting service provider:

$this->app->bind('MyStorage',function($app){
    return new MyStorage($app);
});

And facade is:

class MyStorage extends \Illuminate\Support\Facades\Storage{
}

When using it:

use Namespace\MyStorage\MyStorageFacade as MyStorage;
MyStorage::disk('local');

I get this error:

FatalThrowableError in Facade.php line 237: Call to undefined method Namespace\MyStorage\MyStorage::disk()

Also tried to extend MyStorage form Illuminate\Filesystem\Filesystem and got the same error in other way:

BadMethodCallException in Macroable.php line 74: Method disk does not exist.

2

2 Answers

3
votes

Your MyStorage class needs to extend FilesystemManager not the Storage facade class.

class MyStorage extends \Illuminate\Filesystem\FilesystemManager {
    ....
}
1
votes

A facade is just a convenience class that will convert a static call Facade::method to resolove("binding")->method (more or less). You need to extend from Filesystem, register that in IoC, keep your facade as it is, and use the Facade as a static.

The facade:

class MyStorageFacade extends Facade {      
    protected static function getFacadeAccessor()
    {
        return 'MyStorage'; // This one is fine
    }
}

Your custom storage class:

class MyStorage extends Illuminate\Filesystem\FilesystemManager {
}

In any service provider (e.g. AppServiceProvider)

$this->app->bind('MyStorage',function($app){
   return new MyStorage($app);
});

Then when you need to use it use it as:

MyStorageFacade::disk(); //Should work.