Laravel #can method does not work for all roles - laravel

Problem
The user with the role "author" doesnt see the HTML inside the #can ... endcan block.
Description
Developing a Laravel package and restrict the navbar accordingly to the roles. But when i try to make a nav element only for a user with the role "author", it doesnt work. When i replace "author" with another role, it works.
Maybe my approach is too complicated and proposals for other approaches are welcome as well as hints, where i have to look for solving the problem.
I have a "standard" setup with three tables. One for users, one for roles and one for role_user relations (as it is described here). The relations in the models are set.
You can find the whole project here.
Thanks in advance.
Code
#can('author')
<li class="nav-item">
<a class="nav-link"
href="{{ route('pages.index') }}">{{ __('limplecms::navigation.pages.overview')}}</a>
</li>
#endcan
#canany(['admin', 'editor'])
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown"
aria-expanded="false">
{{ __('limplecms::navigation.pages')}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('pages.index') }}">
{{__('limplecms::navigation.pages.overview')}}
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ route('pages.create') }}">
{{__('limplecms::navigation.pages.create')}}
</a>
</div>
</li>
#endcanany
#can('admin')
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown"
aria-expanded="false">
{{ __('limplecms::navigation.user.management')}}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('users.index') }}">
{{__('limplecms::navigation.users.overview')}}
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ route('users.create') }}">
{{__('limplecms::navigation.users.create')}}
</a>
</div>
</li>
#endcan

Related

How to bind a Navigation-Bar "Dropdown" with asp-controllers and asp-actions . (ASP.Net Core 5 MVC)

Short question: I have searched the internet for an answer but I can't seem to find one that fits my situation.
This is where I want to bind some asp-controllers and asp-actions:
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="Account" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Inloggen</a>
<a class="dropdown-item" href="#">Kleding bekijken</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Uitloggen</a>
</div>
</li>
The dropdown item "Inloggen" should bind the asp-controller 'Account' and asp-action 'Inloggen'.
The dropdown item "Kleding bekijken" should bind the asp-controller 'Outfit' and asp-action 'OutfitsTonen'.
Looks like yours is the standard situation for Anchor Tag Helpers
<a class="dropdown-item"
asp-controller="Account"
asp-action="Inloggen">
Inloggen
</a>

Bootstrap hamburger menu icon won't collapse

I'm trying to add this bootstrap nav menu to my Laravel application, but in smaller screensize when I click on the hamburger icon it won't open.
I checked similar questions here and tried the solutions but none of them worked for me.
I also checked, bootsrap css and js are properly included in the document, in my footer first comes jquery, then popper then bootstrap.js.
Here is my header code:
<header>
<nav class="navbar navbar-expand-lg fixed-top">
<div class="container">
<a class="navbar-brand" href="{{ route('home') }}"><img src="{{ asset('public/assets/frontend/images/logo.png') }}"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<i class="fa fa-navicon" style="color:#fff; font-size:28px;"></i>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" href="{{ route('home') }}">Home</a></li>
<li class="nav-item"><a class="nav-link" href="{{ route('frontend.courses') }}">Courses</a></li>
<li class="nav-item"><a class="nav-link" href="#">Blog</a></li>
<li class="nav-item"><a class="nav-link" href="{{ route('contact') }}">Contact</a></li>
#guest
<li class="nav-item"><a class="btn btn-red" href="{{ route('login') }}">Sign In</a></li>
#else
#if(Auth::user())
<li class="nav-item logged-in">
<div class="dropdown">
<a href="" class="dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user fa-lg" aria-hidden="true"></i> My Dashboard
</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
#if(Auth::user()->role_id == 1)
<a class="dropdown-item" href="{{ url('admin') }}">Admin</a>
#endif
<a class="dropdown-item" href="#">My Profile</a>
<a class="dropdown-item" href="#">Settings</a>
<a class="dropdown-item" href="{{ route('logout') }}" onclick="event.preventDefault();
document.getElementById('logout-form').submit();">Log out</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
</div>
</div>
</li>
#endif
#endguest
</ul>
</div>
</div>
</nav>
</header>
I also have these error messages in the console:
Uncaught TypeError: Cannot convert object to primitive value
at RegExp.test ()
at HTMLDivElement. (collapse.js:346)
at Function.each (jquery-3.5.0.min.js:2)
at S.fn.init.each (jquery-3.5.0.min.js:2)
at S.fn.init.a._jQueryInterface [as collapse] (collapse.js:337)
at HTMLDivElement. (collapse.js:385)
at Function.each (jquery-3.5.0.min.js:2)
at S.fn.init.each (jquery-3.5.0.min.js:2)
at HTMLButtonElement. (collapse.js:381)
at HTMLDocument.dispatch (jquery-3.5.0.min.js:2)
I got it.
Thanks to this answer: https://stackoverflow.com/a/61198996/7133015
This is an incompatibility between bootstrap and kquery (3.5.0). needed to switch back to jquery 3.4.1

Laravel 5.4 - Session closes thanks to a layout

I am not sure how is this happening. On my landing page, I've got a simple statement that returns the user information by using the method "Auth::user()" and alas, it works.
Nevertheless, when applying a layout to my file, I get the "Trying to get property of non-object" exception. I've been playing with it a little then I made it so I can keep the session, but after reloading or moving to another page (which use the same layout, by the way), the session immediately closes itself.
What could be the issue behind this behaviour?
Update: I've found the problem. It seems to be this layout in particular which sets a navbar; it has an iframe that I thought was the problem, but when removing the iframe content (which is inside a modal, that I remove as well), the error keeps hapening - It closes the user's session and throws the exception.
#yield('nav')
<nav class="navbar navbar-dark bg-dark navbar-expand-lg sticky-top">
<a class="navbar-brand" href="/">Printed</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Conóce</a>
</li>
<li class="nav-item">
<a class="nav-link" href="" data-toggle="modal" data-target="#contacto">Contacto</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Catálogo
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/productos">Productos</a>
<a class="dropdown-item" href="/servicios">Servicios</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Promociones</a>
</div>
</li>
<li class="nav-item">
Portafolio de Proyectos
</li>
</ul>
#if(Auth::check() == false)
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Ingresar</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{route('login')}}">Iniciar Sesión</a>
<a class="dropdown-item" href="{{route('register')}}">Registrarse</a>
</div>
</li>
#endif
#if(Auth::check())
<li class="nav-item">
Hello, {{Auth::user()->email}} !
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Opciones</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="">Panel de Usuario</a>
<a class="dropdown-item" href="{{Auth::logout()}}">Cerrar Sesión</a>
</div>
</li>
#endif
</div>
</nav>
Edit: Good news, I've discovered my issue. It seems to be this part in particular that somehow "triggers" itself. Could it be that I'm missing a closure on the tags somewhere?
<a class="dropdown-item" href="{{Auth::logout()}}">Cerrar Sesión</a>

links are not appearing to the auth user

Im using the laravel auth. When a guest user access to the app we should see the links:
Item 1, Item 2, Login and Item 3
When he login, for example with the name John, he should see the links:
Item 1, Item 2, John, Item 3
But its not working, when the user logins just appears the links:
John, Item 3
The Item1 and Item2 dont appears. Do you know why?
<ul class="navbar-nav">
#guest
<li class="nav-item">
<a class="nav-link" href="">Item 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 2</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">Login</a>
</li>
#else
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user" aria-hidden="true"></i> {{ Auth::user()->name }}
</a>
<div class="dropdown-menu" aria-labelledby="userDropdown">
<a class="dropdown-item text-gray" href="{!! url('/item1'); !!}">Login Item 1</a>
<div class="dropdown-divider text-gray"></div>
<a class="dropdown-item text-gray" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
Logout
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST">
{{ csrf_field() }}
</form>
</div>
</li>
#endguest
<li class="nav-item d-none d-lg-block px-0">
<a class="btn btn-outline-primary btn-sm font-weight-bold" href="">
Item 3
</a>
</li>
</ul>
#guest is used for non-login user.
You should change it to
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="">Item 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 2</a>
</li>
#guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">Login</a>
</li>
#endguest
#if(\Auth::check())
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user" aria-hidden="true"></i> {{ Auth::user()->name }}
</a>
<div class="dropdown-menu" aria-labelledby="userDropdown">
<a class="dropdown-item text-gray" href="{!! url('/item1'); !!}">Login Item 1</a>
<div class="dropdown-divider text-gray"></div>
<a class="dropdown-item text-gray" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
Logout
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST">
{{ csrf_field() }}
</form>
</div>
</li>
#endif
<li class="nav-item d-none d-lg-block px-0">
<a class="btn btn-outline-primary btn-sm font-weight-bold" href="">
Item 3
</a>
</li>
</ul>
Everything between #guest and #else will only appear if the user is not logged in.
Putting Item 1 and Item 2 right after the #guest directive means, you want Item 1 and Item 2 to appear if the user it is not logged in
Change you code to
<li class="nav-item">
<a class="nav-link" href="">Item 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 2</a>
</li>
#guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">Login</a>
</li>
#else
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user" aria-hidden="true"></i> {{ Auth::user()->name }}
</a>
<div class="dropdown-menu" aria-labelledby="userDropdown">
<a class="dropdown-item text-gray" href="{!! url('/item1'); !!}">Login Item 1</a>
<div class="dropdown-divider text-gray"></div>
<a class="dropdown-item text-gray" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
Logout
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST">
{{ csrf_field() }}
</form>
</div>
</li>
#endauth
<li class="nav-item d-none d-lg-block px-0">
<a class="btn btn-outline-primary btn-sm font-weight-bold" href="">
Item 3
</a>
</li>
</ul>
You can read more about those directives here
Change it to:
<li class="nav-item">
<a class="nav-link" href="">Item 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 2</a>
</li>
#guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">Login</a>
</li>
#endguest
#auth
<li class="nav-item dropdown">
....
</li>
#endauth
<li class="nav-item d-none d-lg-block px-0">
<a class="btn btn-outline-primary btn-sm font-weight-bold" href="">
Item 3
</a>
</li>

Laravel 4 base/master view

I've recently gotten some problems. There is an model from which I pull some data and things. There is a menu link that I want to be on every page I enter, so I've put it into the base/master view. But the problem is, I need to enter ->with blabla thing on every public function in every controller. How could I not do that? I mean is there anyway around it? I don't want to do that with thingy on every controller method/function. Here's my code:
#if ( Auth::guest() )
<li style="float: right;padding-right: 0">
<ul class="nav">
<li>
<a href="{{ URL::to('register') }}">
<i class="icon-black icon-plus">
</i>
<strong>
Register
</strong>
</a>
</li>
<li>
<a href="{{ URL::to('login') }}">
<i class="icon-black icon-lock">
</i>
<strong>
Log in
</strong>
</a>
</li>
</li>
</li>
</ul>
#else
<li class="divider-vertical">
</li>
<li style="float: right;padding-right: 0">
<div class="btn-group">
<div class="btn btn-primary">
<i class="icon-user">
</i>
{{ (Auth::user()->name) }}
</div>
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
<span class="icon-caret-down">
</span>
</a>
<ul class="dropdown-menu">
<li>
<a href="{{ URL::to('account/managment') }}">
<i class="icon-user">
</i>
Account Managment
</a>
</li>
<li>
<a href="{{ URL::to('account/managment/change_credentials') }}">
<i class="icon-lock">
</i>
Change Password
</a>
</li>
<li class="divider">
</li>
<li>
<a href="{{ URL::to('account/logout') }}">
<i class="icon-off">
</i>
Log out
</a>
</li>
</ul>
</div>
#endif
You can define a View Composer :
View::composer(array('your.first.view','your.second.view'), function($view)
{
$view->with('count', User::count());
});
Everytime you call your view, a user count will be bound to it automatically.
Edit:
About where to use it, it's up to you and it depends on your app, but you might use pp/start/global.php if you don't have a better place to put it. It just have to be executed before your those views.
#Antonio's answer is a good way to do this. You can also use View::share(); to accomplish this with a shorter code.
View::share(array(
'foo' => 'bar'
));

Resources