skip to Main Content

I’m working on a package where classes (‘A’, ‘B’ and ‘C’) are extending a "root" class ‘Foo’.

class Foo {
    public function abc(){
        //
    }
}

class A extends Foo {
    ...
    $this->abc();
    ...
}

class B extends Foo {
    ...
    $this->abc();
    ...
}

class C extends Foo {
    ...
    $this->abc();
    ...
}

In a project implementing this package, it needs to overwrite the method ‘abc’ from the class ‘Foo’.

What would be the proper PHP/Laravel way of doing it?

Is there a way to extend/overwrite a package class like a view can be using the vendor folder? That would be an interesting alternative if possible.

Update

To put in perspective the complexity of the situation. Class ‘A’, ‘B’ & ‘C’ are called in several locations within the package. I cannot just extend class ‘A’ in the application as I would need to redefine the namespace path to all the calls made to the class A within the package.

I am considering creating a facade for class ‘A’, ‘B’ & ‘C’ in the package. That way I would be able to overwrite the facade path in the package AppServiceProvider. But I find this approach a bit "dirty". Thus the reason to seek advise for a cleaner implementation.

2

Answers


  1. Chosen as BEST ANSWER

    Found a workaround.

    The need to extend the method abc was to set the from property within the class Foo (a Mailable object), based on specific parameters of the application. I need to set this property for all the mail sent.

    public function abc(){
        $this->from(getSender());
    }
    

    Since I am using a helpers function bar within the package to call the various classes (A, B & C).

    bar(new A)
    ...
    bar(new B)
    ...
    bar(new C)
    

    The function in package Helpers file before the workaround

    function bar(Foo $mailableObject) {
        ...
        Mail::send(mailableObject);
    }
    

    I created a "hook" by adding a call to an optional function within the function bar. If declared within the application integrating the package, it will allow to perform the desired operations on the class Foo.

    function bar(Foo $mailableObject) {
        ...
        if (function_exists('optionalFunction' {
            Mail::send(optionalFunction(mailableObject));
        } else {
            Mail::send(mailableObject);
        }
    }
    

    In the application helpers file

    function optionalFunction(Foo $mailableObject) {
        // Provided the 'from' method is public
        $mailableObject->from(getSender());
        return $mailableObject;
    }
    
    function getSender() {
        if(condition123()){
            return '[email protected]';
        } else {
            return '[email protected]';
    }
    

    Hope it helps someone in a similar position.


  2. Update

    For this particular case where I need to alter the from name and email of all emails being sent, there is an even easier solution.
    Thanks to this Laracast post.

    All I have to do is overwrite the config values in the AppServiceProvider.

    public function boot() {
        ...
        if(condition123()){
            config(['mail.from.address' => '[email protected]']);
        } else {
            config(['mail.from.address' => '[email protected]']);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search