Laravel 5.2 - Session flash data not set in service provider - laravel

I have created a frontend service provider for my app:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Session;
class FrontendServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
view()->share('message', !is_null(Session::get('message')) ? '<div class="alert alert-success"><strong>Success! </strong>'.Session::get('message').'</div>' : '');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
I am setting a flash message in the controller like so:
public function resend_welcome($token)
{
$user_id = Crypt::decrypt($token);
$user = User::findOrFail($user_id);
if($user->meta->confirmed==1) {
abort(404);
}
Event::fire(new UserRegistered($user));
Session::flash('message', 'A new email has been sent.');
return redirect(route('register.success', $token));
}
Then in my view I am trying to output $message like so:
{{ $message }}
The problem is $message is always NULL. If I use Session::get('message') in my view instead then it works and the flash message is displayed. Why is Session::get('message') always NULL in the service provider even though I have set it in the controller?

In Laravel 5 accessing session information inside a service provider boot method is not possible as the session logic is only started as part of the web middleware group Illuminate\Session\Middleware\StartSession::class.
To share the view variable you can use Middleware for that. Something like:
class BroadcastFlashMessage
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
view()->share('message', !is_null(Session::get('message'))
? '<div class="alert alert-success"><strong>Success! </strong>'.Session::get('message').'</div>'
: '');
return $next($request);
}
}
An alternative is to use laracasts/flash package.

Related

Call to undefined method Illuminate\\Auth\\Access\\Response::authorize()

I'm trying to use Response::authorize() in ContactPolicy.php
but I got this error
Call to undefined method Illuminate\Auth\Access\Response::authorize()
<?php
namespace App\Policies;
use App\models\User;
use App\Contact;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
class ContactPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can permanently delete the contact.
*
* #param \App\models\User $user
* #param \App\Contact $contact
* #return mixed
*/
public function forceDelete(User $user)
{
return $user->role === 'admin'
? Response::allow()
: Response::authorize();
}
}
I visit this website to check Response class Illuminate/Auth/Access/Response.html
then I checked file in my project vendor\laravel\framework\src\Illuminate\Auth\Access\Response.php
in my files I didn't find it ... all i find is this
<?php
namespace Illuminate\Auth\Access;
class Response
{
/**
* The response message.
*
* #var string|null
*/
protected $message;
/**
* Create a new response.
*
* #param string|null $message
* #return void
*/
public function __construct($message = null)
{
$this->message = $message;
}
/**
* Get the response message.
*
* #return string|null
*/
public function message()
{
return $this->message;
}
/**
* Get the string representation of the message.
*
* #return string
*/
public function __toString()
{
return (string) $this->message();
}
}
how this file miss the rest of methods the laravel docs talk about ??
tihs method requires laravel >= 6.x
this method not available in laravel 5
so make sure the laravel version in your project matches the laravel version that you browsing in laravel docs or in laravel API

laravel 6 api resource policy index

The policy does not work on the index apiResource call. Always returns 403..
My ProjectPolicy is this:
class ProjectPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any projects.
*
* #param \App\User $user
* #return mixed
*/
public function viewAny(User $user)
{
return true;
}
...
My ProjectController used this:
class ProjectController extends Controller
{
public function __construct()
{
$this->authorizeResource(ProjectPolicy::class, 'project');
}
...
I registered the policy:
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
Project::class => ProjectPolicy::class,
];
Everything works except the index method call:
/**
* Display a listing of the resource.
*
* #param Request $request
* #return Response
*/
public function index(Request $request)
{
return $request->user()->projects()->get();
}
In the project controller constructor, you need to authorize the resource (model) not the policy itself
public function __construct()
{
$this->authorizeResource(\App\Project::class, 'project');
}
Also make sure that the user making the request is authenticated, can't have guests authorized
But if you want guests to be authorized, you may mark the User model nullable/optional on the Dependency injection on the Policy class
/**
* Determine whether the user can view any projects.
*
* #param \App\User $user
* #return mixed
*/
public function viewAny(?User $user)
{
return true;
}
Hope this helps

Single API use for authenticated and guest user

My laravel application route configured on routes/api.php is.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
Issue is i want to sent list of product but if user authenticated then send product favorite flag 1, and if not authenticated then send return favorite 0
But both case send product list with favorite flag.
If i logged in with my user id and password and send request for see_all_product that time i m getting blank user.
$user = $request->user();
But if i set route like below i m getting user details.
<?php
use Illuminate\Http\Request;
Route::group(['middleware' => 'auth:api'], function(){
Route::post('see_all_product', 'API\ProductController#see_all_product');
});
?>
Now issue is how can i get details if authorization set in the header with same api.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
My see_all_product Function
public function see_all_product(Request $request){
try {
$user = $request->user();
} catch (Exception $ex) {
Log::error($ex);
}
}
API is same for both authenticated and guest user.
I pass authorization token in both case but middleware route i get user details but non middleware route i dont get user information.
Please guide me where i can miss something?
I think you can do it by the way instead of $request->user():
if (auth('api')->check()) {
$user = auth('api')->user();
}
Turn off ['middleware'=> 'auth:api']
use: $request->user('api'); in your controller.
Guests can use the api but user is null;
Auth users can use api as a real user.
alt:
Auth::guard('api')->user();
auth('api')->user();
I didn't test this method on old versions of Laravel, but it should work just fine on the latest ones.
You can create another Middleware that allows ether authenticated or guest users to proceed.
If the user is authenticated then the middleware will prepare the Auth object and auth() function for you.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
class AuthOptional
{
/**
* The authentication factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$this->authenticate($request, $next, $guards);
return $next($request);
}
/**
* Determine if the user is logged in to any of the given guards.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function authenticate($request, $next, array $guards)
{
if (empty($guards)) {
$guards = [null];
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
//If unauthenticated allow the user anyway
$this->unauthenticated($request, $next, $guards);
}
/**
* Handle an unauthenticated user.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function unauthenticated($request, $next, array $guards)
{
return $next($request);
}
}
Import the newly created Middleware under app/Http/kernel.php
protected $routeMiddleware = [
....
'auth.optional' => \App\Http\Middleware\AuthOptional::class
];
And finally use it like this:
<?php
Route::group(['middleware' => ['auth.optional:api']],
});
?>
Now auth()->user() will return the user if user is authenticated and
null if it's not

Efficient update of the table field on each request

I want to update the user table field on each request if the user is authorized. I have not encountered such a task before. I tried to write on the AppServiceProvider.php file:
public function boot()
{
if(Auth::id()) {
$user = User::find(Auth::id());
$user->updated_at = Carbon::now()->setTimezone("America/Los_Angeles");
$user->save();
}
}
But in this case I could not take access to the authorized user.
Can I get access to the service provider to an authorized user?
Or solve this problem with creating middleware?
Note: I am doing this task to find out the time of the user's last activity.
Is the solution found right? Is there a load on the server?
by creating a new middleware try this one
php artisan make:middleware UserActivityUpdateMiddleware
UserActivityUpdateMiddleware
<?php
namespace App\Http\Middleware;
use Closure;
class UserActivityUpdateMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::User()) {
$user = User::find(Auth::user()->id);
$user->updated_at = Carbon::now()->setTimezone("America/Los_Angeles");
$user->save();
}
return $next($request);
}
}

Laravel 5.4: Passing a variable via Request to controller

Generally speaking this should be a rather simple problem. IT should be very similar to the following question on Stack Overflow
But seeing as it has been two years, maybe some of the syntax has changed.
All I want to do is pass a variable from the middleware to the controller, so I'm not duplicating mysql queries.
Here is my middleware:
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$id = $request->user()->id;
$rr = $request->user()->isSuperAdmin();
if ($request->user()->isSuperAdmin()) {
$request->merge(['group' => 123]);
return $next($request);
}
echo "not admin";
}
}
So the middleware works fine and if I DD($request) on the middleware I see my group => 123 on the page. (Right now it's 123 for the sake of simplicity.)
So I want to pass it to my AdminController:
<?php
namespace SleepingOwl\Admin\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use SleepingOwl\Admin\Form\FormElements;
use SleepingOwl\Admin\Form\Columns\Column;
use SleepingOwl\Admin\Display\DisplayTable;
use Illuminate\Contracts\Support\Renderable;
use SleepingOwl\Admin\Display\DisplayTabbed;
use Illuminate\Validation\ValidationException;
use SleepingOwl\Admin\Contracts\AdminInterface;
use SleepingOwl\Admin\Model\ModelConfiguration;
use Illuminate\Contracts\Foundation\Application;
use SleepingOwl\Admin\Contracts\Form\FormInterface;
use SleepingOwl\Admin\Contracts\ModelConfigurationInterface;
use SleepingOwl\Admin\Contracts\Display\ColumnEditableInterface;
class AdminController extends Controller
{
/**
* #var \DaveJamesMiller\Breadcrumbs\Manager
*/
protected $breadcrumbs;
/**
* #var AdminInterface
*/
protected $admin;
/**
* #var
*/
private $parentBreadcrumb = 'home';
/**
* #var Application
*/
public $app;
/**
* AdminController constructor.
*
* #param Request $request
* #param AdminInterface $admin
* #param Application $application
*/
public function __construct(Request $request, AdminInterface $admin, Application $application)
{
$this->middleware('CheckRole');
So as you can see I call the middleware on this constructor. After calling it I should be able do something like:
$request->get('group'); or $request->group;
After trying for quite a while nothing seems to be working and I keep getting a null value. Fundamentally, this shouldn't be terribly difficult, but I seem to have my syntax off or not using the right name spaces?
Instead of this code line:
$request->merge(['group' => 123]);
You can try:
$request->request->add(['group' => 123]);
What this code line will do is if a parameter named group exists in the $request it will overwrite with the new value, otherwise it will add a new parameter group to the $request
In your controller, you can get the value of group parameter as:
$group = $request->group; OR $group = $request->input('group');
Thanks to the joint help of #Rahul-Gupta and #shock_gone_wild. It was a joint effort I guess.
The first issue is that I'm using sleepingOwl laravel boilerplate. Probably not the best idea for someone new to Laravel. (not new to MVC / PHP).
Based on #shock_gone_wild comment, decide move my test over to a simple controller, and not the sleeping owl nonsense. (they have a lot of code.) Anyways, I believe that helped. I did leave the middleware in the constructor because I didn't apply the middleware to the routes.
Then I followed #Rahul-Gupta syntax.
So here is final result, hopefully this will save someone sometime someday...
namespace App\Http\Middleware;
use Closure;
class CheckRole {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
if ($request->user()->isSuperAdmin()) {
$request->request->add(['group' => 123]);
return $next($request);
} else {
echo "not admin";
}
}
}
Then here is the simple controller.
use Illuminate\Http\Request;
use App\task;
use App\User;
use App\HasRoles;
class TaskController extends Controller {
public function __construct() {
// constructor code...
$this->middleware('auth');
$this->middleware('CheckRole');
}
public function index(Request $request) {
$group = $request->input('group');
echo "---->" . $group;
$tasks = Task::all();
return view('test_task', compact('tasks'));
}
}

Resources