For package controllers changing we can use:
class SecondController extends FirstController {
public function new_method() {
\\...
}
//NEED SAME DECLARATION AS IN FirstController
//not practical for controllers which will change their declaration - add or remove arguments
public function old_method(Infopage $info) {
$extendMe = 'extended';
View::composer('welcome', function($view) use( $extendMe ){
$view->with([
'extendMe' => $extendMe,
]);
});
$args = func_get_args();
return parent::old_method( ...$args );
}
}ServiceProvider at register method$this->app->bind(
FirstController::class,
SecondController::class
);decorator class TestControllerDecorator {
private $service;
public function __construct($service) {
$this->service = $service;
}
public function new_method() {
\\...
}
//DO NOT NEED SAME DECLARATION
public function old_method() {
$extendMe = 'extended';
View::composer('welcome', function($view) use( $extendMe ){
$view->with([
'extendMe' => $extendMe,
]);
});
$args = func_get_args();
return $this->service->old_method( ...$args );
}
public function __call($funcname, $args) {
return $this->service->$funcname( ...$args );
}
}ServiceProvider at register method$this->app->extend(TestController::class, function ($service, $app) {
return new TestControllerDecorator($service);
});For package models changing we can use:
Normal class extending - not very practical, because should replace every use of old class with the new class
Note: cannot be bind like controllers, because binding will affect only dependency injected classes, not the ones
used in the workflow.
Use MacroableModel - most package models should use MacroableModel trait, which give dynamic extending
functionality though macros and mixins.
class TestModel {
\\...
use MacroableModel;
\\...
}macro - good for fast functionality extending - bad for project scalingTestModel::macro('new_method', function($arg1) {
\\...
$this->example_for_$this_use($arg1);
\\...
}mixin - good for project scalingClosureclass TestModelMixin {
public function new_method() {
return function($arg1) {
\\...
$this->example_for_$this_use($arg1);
\\...
};
}
}//second argument is to not replace existing `macros`
TestModel::mixin( new TestModelMixin, false );Base class class extending - extend directly the base class that model extends and change whatever need.