diff --git a/README.md b/README.md index 5b6ab93..42f1223 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ You can install the package via composer: ```bash composer require morning-train/laravel-e-conomic ``` +### Configuring the package You can publish the config file with: @@ -24,19 +25,42 @@ php artisan vendor:publish --tag="laravel-e-conomic-config" This is the contents of the published config file: ```php + env('ECONOMIC_APP_SECRET_TOKEN'), 'agreement_grant_token' => env('ECONOMIC_AGREEMENT_GRANT_TOKEN'), + + /* + * This class handles actions on request and response to Economic. + */ + 'request_logger' => \Morningtrain\LaravelEconomic\RequestLogger\VoidRequestLogger::class, ]; + ``` ## Usage +### Creating your own request logger + +A request logger is any class that implements `\Morningtrain\LaravelEconomic\RequestLogger\RequestLogger`. Here's what that interface looks like. + ```php -$laravelEConomic = new Morningtrain\LaravelEConomic(); -echo $laravelEConomic->echoPhrase('Hello, Morningtrain!'); +use GuzzleHttp\Psr7\Response; +use Illuminate\Http\Client\Request; +use Psr\Http\Message\ResponseInterface; + +interface RequestLogger +{ + public function onRequest(Request $request); + + public function onResponse(Response $response): ResponseInterface; +} + ``` +After creating your own `RequestLogger` you must register it in the `request_logger` in the `e-conomic` config file. + ## Testing ```bash diff --git a/config/e-conomic.php b/config/e-conomic.php index e92afca..771ccf1 100644 --- a/config/e-conomic.php +++ b/config/e-conomic.php @@ -3,4 +3,9 @@ return [ 'app_secret_token' => env('ECONOMIC_APP_SECRET_TOKEN'), 'agreement_grant_token' => env('ECONOMIC_AGREEMENT_GRANT_TOKEN'), + + /* + * This class handles actions on request and response to Economic. + */ + 'request_logger' => \Morningtrain\LaravelEconomic\RequestLogger\VoidRequestLogger::class, ]; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 6ee315f..64cfe56 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -10,7 +10,6 @@ parameters: checkOctaneCompatibility: true checkModelProperties: true checkMissingIterableValueType: false - ignoreErrors: - - '#Call to an undefined static method Illuminate\\Support\\Facades\\Http::economic\(\)#' + treatPhpDocTypesAsCertain: false diff --git a/src/LaravelEconomicServiceProvider.php b/src/LaravelEconomicServiceProvider.php index c56fcc1..4c24693 100644 --- a/src/LaravelEconomicServiceProvider.php +++ b/src/LaravelEconomicServiceProvider.php @@ -2,10 +2,14 @@ namespace Morningtrain\LaravelEconomic; +use GuzzleHttp\Psr7\Response; use Illuminate\Http\Client\PendingRequest; +use Illuminate\Http\Client\Request; use Illuminate\Support\Facades\Http; +use InvalidArgumentException; use Morningtrain\Economic\Services\EconomicApiService; use Morningtrain\LaravelEconomic\Drivers\HttpEconomicDriver; +use Morningtrain\LaravelEconomic\RequestLogger\RequestLogger; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -13,7 +17,21 @@ class LaravelEconomicServiceProvider extends PackageServiceProvider { public function boot() { + $this->app->singleton(RequestLogger::class, config('e-conomic.request_logger')); + Http::macro('economic', function (): PendingRequest { + /** @var RequestLogger $logger */ + $logger = app(RequestLogger::class); + + if (! is_subclass_of($logger, RequestLogger::class)) { + throw new InvalidArgumentException( + sprintf( + 'The request logger must implement the %s interface', + RequestLogger::class + ) + ); + } + /** @var \Illuminate\Http\Client\Factory $this */ return $this ->withHeaders([ @@ -21,6 +39,12 @@ public function boot() 'X-AgreementGrantToken' => config('e-conomic.agreement_grant_token'), 'Content-Type' => 'application/json', ]) + ->beforeSending( + fn (Request $request) => $logger->onRequest($request) + ) + ->withResponseMiddleware( + fn (Response $response) => $logger->onResponse($response) + ) ->throw(); }); diff --git a/src/RequestLogger/RequestLogger.php b/src/RequestLogger/RequestLogger.php new file mode 100644 index 0000000..d9a06dc --- /dev/null +++ b/src/RequestLogger/RequestLogger.php @@ -0,0 +1,14 @@ +onRequestCalledTimes++; + } + + public function onResponse(Response $response): ResponseInterface + { + $this->onResponseCalledTimes++; + + return $response; + } +} diff --git a/tests/Unit/RequestLoggerTest.php b/tests/Unit/RequestLoggerTest.php new file mode 100644 index 0000000..a083ab0 --- /dev/null +++ b/tests/Unit/RequestLoggerTest.php @@ -0,0 +1,23 @@ +instance(RequestLogger::class, new TestRequestLogger()); +}); + +it('calls request logger before and after request', function () { + $logger = app(RequestLogger::class); + + Http::fake([ + 'https://restapi.e-conomic.com/customers*' => Http::response([]), + ]); + + Customer::where('name', 'Morningtrain')->first(); + + expect($logger->onRequestCalledTimes)->toBe(1); + expect($logger->onResponseCalledTimes)->toBe(1); +});