zeomega
zeomega

Reputation: 355

Laravel 5 Override a class method

I would like to override the method setContent() of the class Illuminate\Http\Response as :

<?php 
namespace MyNameSpace\MyClass;

use Illuminate\Http\Response;
class myResponse extends Reponse {
   public function setContent($content)
     // Something
   }
}

But I don't know how to tell Laravel to load my class instead of the original one.

Upvotes: 3

Views: 16382

Answers (3)

aimme
aimme

Reputation: 6773

Too late, but as i came up with same issue. but for reference i would want to post how i resolved this issue.

When i wanted to handle all the the response by myself without using a response macro or transformer and TO OVERRIDE MANY OTHER FRAMEWORK DEFAULT METHODs . this is how i completely took control of the response object.

just posted here for reference as i in my opinion it solves the problem in a clearer way.

Lot of overriding as its done through pipeline and routing and so it`s registered as base service provider. here is how i managed to override all.

here I am using laravel 5.3

1 - create a new response class

<?php

namespace App\Extensions\Illuminate\Http;

// use Illuminate\Http\Response as BaseResponse;
use Symfony\Component\HttpFoundation\Response as BaseResponse;

class Response extends BaseResponse
{
    public function setContent($content)
    {
        //do what ever you want to do with the content
        //dd($content);
    }
}

2 - create a new router and use the new response

<?php

namespace App\Extensions\Illuminate\Routing;

use Illuminate\Http\Request;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Routing\Router as IlluminateRouter;
use App\Extensions\Illuminate\Http\Response;

class Router extends IlluminateRouter
{

    public function prepareResponse($request, $response)
    {
        if ($response instanceof PsrResponseInterface) {
            $response = (new HttpFoundationFactory)->createResponse($response);
        } elseif (! $response instanceof SymfonyResponse) {
            $response = new Response($response);
        }

        return $response->prepare($request);
    }
}

3 - create new routing service provider use new router

<?php

namespace App\Providers;

use Illuminate\Routing\RoutingServiceProvider as ServiceProvider;
use App\Extensions\Illuminate\Routing\Router;


class RoutingServiceProvider extends ServiceProvider
{
    protected function registerRouter()
    {
        $this->app['router'] = $this->app->share(function ($app) {
            return new Router($app['events'], $app);
        });
    }
}

4 - create new Application class and use new routing service provider

<?php

namespace App\Extensions\Illuminate\Foundation;

use Illuminate\Events\EventServiceProvider;
use Illuminate\Foundation\Application as App;
use App\Providers\RoutingServiceProvider;

class Application extends App
{
    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));

        $this->register(new RoutingServiceProvider($this));
    }
}

5 - and finally in bootstrap\app.php use the new Application

// $app = new Illuminate\Foundation\Application(
//     realpath(__DIR__.'/../')
// );
$app = new App\Extensions\Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

Upvotes: 3

Emeka Mbah
Emeka Mbah

Reputation: 17555

You need to create a facade like so

<?php namespace App\Facades;

use Illuminate\Support\Facades\Response as BaseResponse;

class Response extends BaseResponse {

    public static function overwriteMethod()
    {
        //
    }

}

Then go to config/app.php under facades comment out this line

//'Response'  => 'Illuminate\Support\Facades\Response',

Then add this to the facades stack

'Response'  => 'App\Facades\Response',

Upvotes: 1

Korvin Szanto
Korvin Szanto

Reputation: 4501

You will need to extend the Response facade to reflect the class you have, then change your applications /config/app.php to link to your new facade rather than laravels.

Upvotes: 1

Related Questions