newrelic for laravel to track routes response time - php

I am trying to add newrelic to my laravel site. I found this repo. But couldn't use it properly.
Where should I put this code?
App::after( function() {
Newrelic::setAppName( 'MyApp' );
} );
Or maybe other ways to add routes response time to newrelic...

App::after does not exists anymore.
You can register a middleware that is executed after the request to do what you need:
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
Newrelic::setAppName( 'MyApp' );
return $response;
}
}
and register it as usually in app/Http/Kernel.php:
protected $middleware = [
...,
\App\Http\Middleware\AfterMiddleware::class
];

Related

how to redirect properly using a global middleware in Laravel?

I created a custom middleware to redirect short urls to other urls, I have a Url model that has this information:
{
"id":1,
"original_url":"http://www.google.com",
"short_url":"http://127.0.0.1:8000/wGjxw",
"updated_at":"2023-02-08T21:05:39.000000Z",
"created_at":"2023-02-08T21:05:39.000000Z"
}
so I have created a middleware:
<?php
namespace App\Http\Middleware;
use App\Models\Url;
use Closure;
use Illuminate\Http\Request;
class RedirectMiddleware
{
public function handle(Request $request, Closure $next)
{
//dd('here'); // is not reaching this code
$url = Url::where('short_url', $request->fullUrl())->first();
if ($url) {
return response()->redirectTo($url->original_url);
}
return $next($request);
}
}
app/Http/Kernel.php
....
....
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\RedirectMiddleware::class,
...
...
But, when I hit the url http://127.0.0.1:8000/wGjxw I get a 404 error,
This is the web.php
Route::get('/', function () {
return view('main');
});
Route::post('/urls', [UrlsController::class, 'store'] );
These routes are for showing the page with the form, and for creating the short url and those are working properly, the problem is that it looks like the middleware is not registered or I don't know what is happening, what I want is the short_url gets redirected to the original_url, what can I do? thanks
If the middleware approach isn't working, you could make a route specifically for it using route model binding with short_url as the key.
https://laravel.com/docs/9.x/routing#customizing-the-key
Route::get('/{url:short_url}', fn (Url $url) => redirect()->away($url->original_url));
My error was that the middleware was in the $middlewareGroups property, and it should be in the $middleware property, now it is working properly

PHP Laravel protected route for subpage without authentication

I'm building a Laravel-app and I have a route where I need to include a third-party script/iframe. I want to protect that route with a simple access code without setting up the laravel-authentication.
Is that possible? If so, how can I achieve that?
All solutions I give below suggest you are trying to access your route with code=X URI/GET parameter.
Simple Route
You can simply check for the given code to be correct in each route's method, and redirect somewhere if that's not the case.
web.php
Route::get('yourRouteUri', 'YourController#yourAction');
YourController.php
use Request;
class YourController extends Controller {
public function yourAction(Request $request) {
if ($request->code != '1234') {
return route('route-to-redirect-to')->redirect();
}
return view('your.view');
}
}
Route with middleware
Or you can use middlewares for avoiding to repeat the condition-block in each route if you have many of them concerned by your checking.
app/Http/Middleware/CheckAccessCode.php
namespace App\Http\Middleware;
use Request;
use Closure;
class CheckAccessCode
{
public function handle(Request $request, Closure $next)
{
if ($request->code != '1234') {
return route('route-to-redirect-to')->redirect();
}
return $next($request);
}
}
app/Http/Kernel.php
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
// Other middlewares...
'withAccessCode' => \App\Http\Middleware\CheckAccessCode::class,
];
web.php
Route::get('yourRouteUri', 'YourController#yourAction')->middleware('withAccessCode');
You can create your own middleware.
Register the middleware in the $routesMiddleware of your app/Http/Kernel.php file.
Then use it like this:
Route::get('script/iframe', 'YourController#index')->middleware('your_middleware');
-- EDIT
You can access the route like this:
yoururl.com/script/iframe?code=200
Then in the middleware handle method:
if ($request->code !== 200) {
// you don't have access redirect to somewhere else
}
// you have access, so serve the requested page.
return $next($request);

Laravel Parameter in every url

I have read almost everything in web and documentation but i can't find solution for my Problem.
I have a variable stored in Session , then I want to put this variable in every url generated by route('some-route') .
In Session I have sub = "mysubid"
When I generate Route route('my-route') I want to pass this sub parameter in query string: http://domain.dom/my-route-parameter?sub=mysubid
Can you help me to solve This problem? Any helpful answer will be appreciated;
You can use the Default Values feature.
First create a new middleware php artisan make:middleware SetSubIdFromSession. Then do the following:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubIdFromSession
{
public function handle($request, Closure $next)
{
URL::defaults(['sub' => \Session::get('sub')]);
return $next($request);
}
}
At the end register your new middleware in app/Http/Kernel.php by adding it to $routeMiddleware.
protected $routeMiddleware = [
// other Middlewares
'sessionDefaultValue' => App\Http\Middleware\SetSubIdFromSession::class,
];
Add {sub} and the middleware to your route definition:
Route::get('/{sub}/path', function () {
//
})
->name('my-route')
->middleware('sessionDefaultValue');
Since you want this on every web route you can also add the middleware to the web middleware group:
protected $middlewareGroups = [
'web' => [
// other Middlewares
'sessionDefaultValue',
],
'api' => [
//
]
];
Try this , You need to create middleware php artisan make:middleware SetSubSession
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\URL;
class SetSubsSession
{
public function handle($request, Closure $next)
{
if(session('sub')){
$url = url()->full();
return redirect($url.'?sub='.session('sub'));
}
return $next($request);
}
}
in app/http/Kernel.php
protected $routeMiddleware = [
........
'setsubsession' => \App\Http\Middleware\SetSubsSession::class,
]
in route.php add
Route::group(['middleware' => 'setsubsession'], function(){
//and define all the route you want to add sub parameter
});
using this you don't need to change all your routes.This will automatic add "sub" in the route define in that middleware.

How to log every response in laravel 5.2 framework

I was using below code for logging each and every request and response for my API but now it's not working for Laravel 5.2.
I have tried to use https://laravel.com/docs/5.2/middleware#terminable-middleware but not succeed.
use Closure;
use Illuminate\Contracts\Routing\TerminableMiddleware;
use Illuminate\Support\Facades\Log;
class LogAfterRequest implements TerminableMiddleware {
public function handle($request, Closure $next)
{
return $next($request);
}
public function terminate($request, $response)
{
$logFile = 'log.txt';
Log::useDailyFiles(storage_path().'/logs/'.$logFile);
Log::info('app.requests', ['request' => $request->all(), 'response' => $response->getContent()]);
}
}
Can anyone suggest me the solution?
Assuming you use web group for your routes.php, you should add in app/Kernel.php in $middlewareGroups for web the following middleware:
\App\Http\Middleware\LogAfterRequest ::class,
Your routes.php should look like this:
Route::group(['middleware' => 'web'], function () {
// here you put all the routes
});
I have got the solution. the issue was that i have added "die" in controller method due to which terminate function is not executing and so no log generated.

Laravel Set up User Language

I have many controllers and I want to set this code in the all of this(actually all of project), how can i do that?
if( !empty(Input::get('lan')) ){
Auth::user()->language = Input::get('lan');
App::setLocale( Auth::user()->language );
}else{
App::setLocale( Auth::user()->language );
}
You can use Laravel's middleware for that. Middleware is a layer of code that wraps the request processing and can execute additional code before or/and after request is processed.
First, you need your middleware class. It needs to have one method called handle() that will do the desired logic. In your case it could look like that:
<?php namespace App\Http\Middleware;
use Auth;
use App;
class SetLang {
public function handle($request, Closure $next) {
if(empty($request->has('lan'))) {
if (Auth::user()) {
Auth::user()->language = $request->input('lan');
Auth::user()->save(); // this will do database UPDATE only when language was changed
}
App::setLocale($request->input('lan'));
} else if (Auth::user()) {
App::setLocale(Auth::user()->language);
}
return $next($request);
}
}
Then register the middleware in your App\Http\Kernel class so that it gets executed for every request:
protected $middleware = [
//here go the other middleware classes
'App\Http\Middleware\SetLang',
];
You can find more info about Middleware in the docs here: http://laravel.com/docs/master/middleware
Seems that with newest versions of Laravel (im on 5.8) for this middleware to work you need to place it under $middlewareGroups otherwise the call to Auth::user() its always empty.
Following jedrzej-kurylo answer, just move the middleware to:
protected $middlewareGroups = [
'web' => [
...
'App\Http\Middleware\SetLang',
],
];

Categories