I am wanting to find out how I can pass in roles as an array because when I try to do this in my construct of my controller it always seems to only be Administrator.
The following is my app/controllers/UserscController.php
class UsersController extends BaseController {
public function __construct()
{
parent::__construct();
$this->beforeFilter('role:Administrator,Owner');
}
}
The following is my app/filters.php
Route::filter('role', function($route, $request, $roles)
{
if(Auth::guest() !== true)
{
if(!empty($roles))
{
$roles = explode(',', $roles);
if(count($roles) > 0)
{
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
}
}
return Redirect::to('/youshallnotpass');
}
});
You can set the roles as a parameter in your controller. To load the roles into your filter you would do this:
Route::filter('role', function($route, $request)
{
if(Auth::guest() !== true)
{
$roles = $route->parameter('roles');
if(!empty($roles))
{
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
}
return Redirect::to('/youshallnotpass');
}
});
Note:
Before laraval 4.1 you would use: $roles = $route->getParameter('roles'); instead of $roles = $route->parameter('roles');
Hope this helps!
Laravel already explodes your filter parameters on the comma, to allow passing multiple parameters to a filter. So, in your case, you've actually passed two parameters to your filter: the first parameter has the value 'Administrator', and the second parameter has the value 'Owner'.
So, two quick options are:
Change the delimiter you're using in your string. In your controller: $this->beforeFilter('role:Administrator;Owner'); and then in your filter: $roles = explode(';', $roles);
Or, leave your controller code alone and use PHP's func_get_args() function in your filter:
Route::filter('role', function($route, $request)
{
if(Auth::guest() !== true)
{
$roles = array_slice(func_get_args(), 2);
foreach($roles as $role)
{
if (Auth::user()->role->role_name == $role)
{
return;
}
}
return Redirect::to('/youshallnotpass');
}
});
Related
NOTE: this is for an endpoint. not for a form request.
let's say I have middleware named Inputs which has this code in the handle()
public function handle(Request $request, Closure $next) {
$data = $request->all();
foreach ($data as $array) {
//HOW TO USE THE CUSTOM RULE HERE?
}
return next($request);
}
here's the custom rule App\Rules
class MyRule {
public function construct() {}
public function passes($attribute, $value) {
if ($value > 1) {
return false;
}
return true;
}
public function message() {
return "data invalid";
}
}
laravel 5:8
I create roles,permissions,permission_role,role_user
And in AuthServiceProvider:
public function boot()
{
$this->registerPolicies();
$permissions = $this->getPermissions();
if ($permissions) {
foreach ($permissions as $permission) {
Gate::define($permission->name, function ($user) use ($permission) {
return $user->hasRole($permission->roles);
});
}
}
}
protected function getPermissions()
{
if (\Schema::hasTable('permissions')) {
return Permission::with('roles')->get();
}
return null;
}
I try use can in route:
$can = 'can:manage_global';
Route::get('/create', 'ProductController#create')->middleware($can)->name('panel.product.create');
it works.
But how can use multi can?
I try this:
$can = 'can:manage_global,manage_articles';
but it works only for manage_global not manage_articles.
$can = 'can:manage_global|manage_articles';
Try this with your desired condition, I applied | (OR) between both permissions conditions
I am trying to determine if a user has the ability to update a model in a global scope, but I am using permission prefixes that I normally get through a relation.
The apply code is as follows:
public function apply(Builder $builder, Model $model)
{
$user = getUser();
if ($user === null || $user->cannot('update', $model)) {
$builder->where('active', '=', 1);
}
}
When I dd($model) the model is not actually instantiated so when I do my update permission check in my policy:
public function update(User $user, Item $item)
{
return $user->hasAnyPermission(['edit-things', $this->prefix($item) . "-edit-item"]);
}
Where the prefix function looks like:
private function prefix(Item $item = null)
{
if ($item !== null) {
return $item->parentRelation->roles_permission_prefix;
}
$parentRelation= ParentRelation::findOrFail(request('parent_relation_id'));
return $parentRelation->roles_permission_prefix;
}
It all fails due to their actaully not being a relationship. Any ideas?
Quick Edit: I am using the Spatie Permissions library if that is pertinent.
The only function that would break on a missing relationship is the prefix() function.
You can prevent prefix() from being called by checking if both $model and $model->parentRelation are null too in your list of conditions:
public function apply(Builder $builder, Model $model)
{
$user = getUser();
if ( $user === null
|| $model === null
|| (method_exists($model, 'parent_relation') && !$model->parentRelation)
|| $user->cannot('update', $model)
) {
$builder->where('active', '=', 1);
}
}
I am using laravel 5.4 and I want to filter search. its my front-end
my code looks like this
class DeviceFilterController extends Controller
{
public function filter(Feature $feature){
$marks = isset($_POST["mark"]) ? $_POST["mark"] : null;
$feature = $feature->newQuery();
if(isset($marks ))
{
foreach ($marks as $value)
{
$feature->where('device_mark', $value);
}
}
return $feature->get();
}
}
that result just one entry
You could take a different approach using whereIn(), assuming you mark input is an array of IDs like [1, 4, 8, 22].
public function filter(Request $request)
{
$features = Feature::when($request->has('mark'), function($query) use ($request) {
return $query->whereIn('device_mark', $request->mark); //Assuming you are passing an array of IDs
})->get();
return $features;
}
when() closure will only executes when you are sending 'mark' input. Doing it without when would look like this
public function filter(Request $request)
{
$features = [];
if ( $request->has('mark') && $request->mark != '' ) {
$features = Feature::whereIn('device_mark', $request->mark)->get();
} else {
$features = Feature::get();
}
return $features;
}
I have 2 many to many relationships and trying to get all related data.
User model:
public function roles()
{
return $this->belongsToMany('App\Role', 'user_role_pivot', 'user_id', 'role_id');
}
Role model:
public function rolepermissions()
{
return $this->belongsToMany('App\RolePermission', 'role_permissions_connect', 'role_id', 'role_perm_id');
}
I'm making policies and want to get all values from my rolepermissions.
my policy:
public function createrole(User $user)
{
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
return $permission->permission_name;
}
}
}
It only returns only one result, but i want to get all related data from role permissions.
As soon as a function hits return, it stops to execute and returns the result. It's different than for example yield return in C# where you can actually return multiple values.
Anyways, You might want to add everything to an array and then use your array to execute actions, like this:
public function createrole(User $user) {
$array = [];
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
array_push($array, $permission);
}
}
dd($array); //add this line if you want to see your array's items
foreach($item in $array){
//do something
}
}
Now that we're doing best practices anyways, you can also do this:
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $key => $permission) {
$array[$key] = $permission;
}
}
Which is performance-wise probably more efficient.
You're returning $permission->permission_name
so the return forces the function to stop executing. You're better off returning an array.
$roles = [];
foreach ($user->roles as $role) {
foreach ($role->rolepermissions as $permission) {
$roles[] = $permission->permission_name;
}
}
}
return $roles;