how to restrict access to certain parts of a view laravel - php

i want to restrict certain parts of a view if a user is not a guest/admin is not supposed to see.the application has 3 users admin,vendor,customer
#if (Auth::check() && !Auth::user()->role == 'customer')
<div class="collapse show" id="users-nav">
<ul class="nav nav-sm flex-column">
<li class="nav-item">
<a class="nav-link" href="{{ route('profile.edit') }}">
{{ __('User Profile') }}
</a>
</li>
am getting the error
The vendor doesnt see too that part and i want him to see together with admin

You should change your if clause from this:
#if (Auth::check() && !Auth::user()->role == 'customer')
To this:
#if (Auth::check() && !(Auth::user()->role == 'customer'))
Or to this (as pointed by #miken32), easier to read:
#if (Auth::check() && (Auth::user()->role !== 'customer'))
The first one is always false, pay attention to round brackets.

Blade provides several shortcuts for checking if a user is signed in. for example:
#auth
<p>Only logged in users can view this</p>
Logout
#endauth
#guest
<p>Only non-logged in users can view this</p>
Login
#endguest
You can view additional blade templating if statements here: https://laravel.com/docs/5.8/blade#if-statements

Related

Multi Auth Laravel

I have just created multiple authentication laravel sucessfully. When i use these statement below, it has a little proplem.
#if(Auth::guard('student')->check())
<li><span style="color: white">Xin chào </span><a href="#" >{{Auth::guard('student')->student()->name}}</a></li>
#else
<li><a href="{{route('student.login')}}" >Login</a>
</li>
#endif
This Error is :
Method student does not exist.
Yes, i haven't yet created method student.
But if i change as {{Auth::guard('student')->user()->name}}.That's okay, it will display that name.
I don't know where it is i have to create student Method.
Inside the #if statement, you've already checked that a user with the guard 'student' is logged in, you don't need to check for that again, hence you can do something like this and it should work:
#if(Auth::guard('student')->check())
<li><span style="color: white">Xin chào </span><a href="#" >{{ Auth::user()->name }}</a></li>
#else
<li><a href="{{route('student.login')}}" >Login</a></li>
#endif

#if (Auth::user() == $image->user_id) doesn't work even though logged user has id of 1 and $image->user_id has id 1 as well

I'm trying to display the delete image button only if the logged user is the one who has uploaded the image. Unfortunately, when I do that, the delete image button disappears even though the logged user is the creator of the images. I do not see why would that not work correctly.
<div class="wrapper">
<div class='imageContainer'>
<h1 class='imageTitle'>{{$image->name}}</h1>
<div class="stickyImageContainer">
<img class='uploadedRealImage' src='/storage/images/uploaded/{{$image->file_name}}' alt='Random image'/>
#if (Auth::user() == $image->user_id)
<div class='deleteImageButton'></div>
<a class='deleteImageA' href='{{ route('deleteImage', ['image_id' => $image->id]) }}'>X</a>
#endif
</div>
</div>
</div>
You're trying to compare User object with integer. So, change it to:
#if (Auth::id() === $image->user_id)
Also, you should use policies for this:
#can('delete', $image)

Getting error when a user is not logged in because Auth::user()->hasRole('Admin')` can not check if the user has role of admin in Laravel

I have an a tag that works as a delete button for an image, however, in my blade template I display the button only to the uploader of the image or the admins of the website. Unfortunately, when a user is not logged, I get an error because Auth::user()->hasRole('Admin') can not check if the user has role of admin. Any idea how am I supposed to avoid this problem?
The error:
"Call to a member function hasRole() on null"
My code
<div class="wrapper">
<div class='imageContainer'>
<h1 class='imageTitle'>{{$image->name}}</h1>
<div class="stickyImageContainer">
<img class='uploadedRealImage' src='/storage/images/uploaded/{{$image->file_name}}' alt='Random image'/>
#if (Auth::id() === $image->user_id || Auth::user()->hasRole('Admin'))
<div class='deleteImageButton'></div>
<a class='deleteImageA' href='{{ route('deleteImage', ['image_id' => $image->id]) }}'>X</a>
#endif
</div>
</div>
</div>
You need to check if Auth::user() returned a model or just null first:
#if (Auth::id() === $image->user_id || (Auth::user() && Auth::user()->hasRole('Admin')))
It's probably cleaner to break these into two nested :
#if(Auth::user())
#if(Auth::id() === $image->user_id || Auth::user()->hasRole('Admin'))
or even better, use Laravel's authorization gates to encompass this logic, which will allow you to do:
#can('delete', $image)
Use auth()->check() prior to attempting to access the user's role.
#if(auth()->check() && Auth::user()->hasRole('Admin'))
....
#endif
Laravel also offers the can and cannot blade directives. See: https://laravel.com/docs/5.5/authorization#via-blade-templates

Laravel Pagination "Three Dots" Separator customization

Im currently using Laravel 5.3 and was wondering if there is a option for the customization of the Three Dots deperator. (skips page 9-10, which is to late)
Example
Currently the Three dots initiate if there are more than 11 pages... Which isnt quiet useful if your site is responsive. if there are to many pages so it breaks into 2 lines.
Example2
I cannot find anything regarding there being options for $resource->links(). But if there is please tell me! Much appreciated.
Edit: it has to do with the following function:
vendor/laravel/framework/src/Illuminate/Pagination/LengthAwarePaginator.php (page: 128, render()). The current function does not support a second variable. So i guess i have to rebuild it?
This is a solution for Laravel 5.5+. Here is what it does:
Shows the first and the last page.
Shows previous and next two pages from the current page.
Three dots only appear on the left after the current page is greater than 4.
Three dots only appear on the right after the current page is less than the 4 - (count of pages).
<!-- Pagination Elements -->
#foreach ($elements as $element)
<!-- Array Of Links -->
#foreach ($element as $page => $url)
<!-- Use three dots when current page is greater than 4. -->
#if ($paginator->currentPage() > 4 && $page === 2)
<li class="page-item disabled"><span class="page-link">...</span></li>
#endif
<!-- Show active page else show the first and last two pages from current page. -->
#if ($page == $paginator->currentPage())
<li class="page-item active"><span class="page-link">{{ $page }}</span></li>
#elseif ($page === $paginator->currentPage() + 1 || $page === $paginator->currentPage() + 2 || $page === $paginator->currentPage() - 1 || $page === $paginator->currentPage() - 2 || $page === $paginator->lastPage() || $page === 1)
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
#endif
<!-- Use three dots when current page is away from end. -->
#if ($paginator->currentPage() < $paginator->lastPage() - 3 && $page === $paginator->lastPage() - 1)
<li class="page-item disabled"><span class="page-link">...</span></li>
#endif
#endforeach
#endforeach
Output:
Page 1 (first page)
Page 3
Page 10 (last page)
Option 1 :
You can customize default files but don't change vendor files directly. Publish them and then add modifications to that.
php artisan vendor:publish --tag=laravel-pagination
This command will automatically create the folder /resources/views/vendor/pagination and you have your files for modification.
You can get more information here : laravel pagination
Option 2:
Maybe you want to get rid of the files that are generated by default. Or, perhaps you want to assign another file to be responsible for your default pagination view.
All of this is possible, but you will need to inform the AppServiceProvider for this action by calling the new pagination views in the boot() method:
use Illuminate\Pagination\Paginator;
public function boot(){
Paginator::defaultView('your-pagination-view-file-name');
Paginator::defaultSimpleView('your-pagination-view-file-name');
}
Get information for defaultView and defaultSimpleView here :laravel pagination
I have created new file for pagination and added in AppServiceProvider.
#if ($paginator->hasPages())
<ul class="blog-pagenation">
{{-- Previous Page Link --}}
#if ($paginator->onFirstPage())
<li class="disabled"><a>«</a></li>
#else
<li>«</li>
#endif
#if($paginator->currentPage() > 3)
<li class="hidden-xs">1</li>
#endif
#if($paginator->currentPage() > 4)
<li><a>...</a></li>
#endif
#foreach(range(1, $paginator->lastPage()) as $i)
#if($i >= $paginator->currentPage() - 2 && $i <= $paginator->currentPage() + 2)
#if ($i == $paginator->currentPage())
<li class="active"><a class="active">{{ $i }}</a></li>
#else
<li>{{ $i }}</li>
#endif
#endif
#endforeach
#if($paginator->currentPage() < $paginator->lastPage() - 3)
<li><a>...</a></li>
#endif
#if($paginator->currentPage() < $paginator->lastPage() - 2)
<li class="hidden-xs">{{ $paginator->lastPage() }}</li>
#endif
{{-- Next Page Link --}}
#if ($paginator->hasMorePages())
<li>»</li>
#else
<li class="disabled"><a>»</a></li>
#endif
</ul>
#endif
By using this i am able to get 3 dots in starting and ending you have to customize classes based on your themes.
Adding to the previous response, once you generate the vendor view files with the artisan command php artisan vendor:publish you can create a new one in that folder and call it for example custom.blade.php and put the following code:
#if ($paginator->hasPages())
<ul class="custom-pagination">
{{-- Previous Page Link --}}
#if ($paginator->onFirstPage())
<li class="disabled pageNumber"><span>« Prev</span></li>
#else
<li><a class="pageNumber" href="{{ $paginator->previousPageUrl() }}" rel="prev">«</a></li>
#endif
{{-- Pagination Elements --}}
#foreach ($elements as $element)
{{-- Array Of Links --}}
#if (is_array($element))
#foreach ($element as $page => $url)
#if ($page === $paginator->currentPage())
<li class="active pageNumber"><span>{{ $page }}</span></li>
#elseif (($page === $paginator->currentPage() + 1 || $page === $paginator->currentPage() + 2)
|| $page === $paginator->lastPage())
<li><a class="pageNumber" href="{{ $url }}">{{ $page }}</a></li>
#elseif ($page === $paginator->lastPage()-1)
<li class="disabled"><span>...</span></li>
#endif
#endforeach
#endif
#endforeach
{{-- Next Page Link --}}
#if ($paginator->hasMorePages())
<li><a class="pageNumber" href="{{ $paginator->nextPageUrl() }}" rel="next">Next »</a></li>
#else
<li class="disabled pageNumber"><span>Next »</span></li>
#endif
</ul>#endif
The important part of the code for the three dots is in the {{-- Array Of Links --}} portion. I think this more or less does what you need but may require additional tweaking.
then you can use it in your view like this:
<div class="pagination">
#if ($users instanceof \Illuminate\Pagination\LengthAwarePaginator)
{{ $users->links('vendor.pagination.custom') }}
#endif
</div>

A better way to improve blade template?

There are two type of packages that a customer can choose from: Phone packages or Broadband & Phone Packages.
When user ready to place an order, it will show a summary view with package name information and the cost. Some Summary information does not need to show if they select Phone package or Broadband & Phone Package.
Is there a better way to improve the readability and maintainable? For example
order-sidebar.blade.php
Note: This is small example of block of code. In the real application it is quite large with a lot of if statement broadbandphone or phone
#if ($summary['service'] == "phone" || $summary['service'] == "broadbandphone")
<div class="x5">
<h4>Phone Line x <span class="summary-lines">{{$summary['lines']}}</span></h4>
<ul class="clearfix">
#if ($summary['service'] == "phone")
<li>
<p class="x5-details">
#if ($summary['line_type'] == "newline")
New Line(s)
#endif
#if ($summary['line_type'] == "switch")
Switch line(s)
#endif
</p>
</li>
#endif
#if ($summary['service'] == "phone" && $summary['lines'] > 1)
<li>
<p class="x5-details">{{$summary['linesWithMulitpleNumbers']}}</p>
</li>
#endif
<li>
<p class="x5-details">{{$summary['package']->name}}</p>
<p class="x5-price">£{{$summary['monthlyLinesCost']}}</p>
</li>
</ul>
</div>
#endif
Or should I do two separate files for summary view like order-sidebar-phone.blade.php and order-sidebar-broadbandphone.blade.php
So it would be something like this:
#if ($summary['service'] == "phone")
#include('sections.order-sidebar-phone')
#end
#if ($summary['service'] == "broadbandphone")
#include('sections.order-sidebar-broadbandphone')
#end
You code looks okay to me. However here are some tips that might help reducing if's or making your code more readable.
Shorthand ternary if
Sometimes a shorthand if looks cleaner and more readable:
#if($summary['service'] == "phone")
Foo
#else
Bar
#endif
Can be written as:
{{ ($summary['service'] == "phone" ? "Foo" : "Bar") }}
It's especially useful for just little pieces of text that change depending on a condition.
Indentation
I shouldn't even need to say that. Indent your code right (not saying you didn't in your question...) And your if statements will be less confusing ;)
Partials
While it is an option to split it up completely like you suggested, this can cause a lot of duplicate code...
But you can also split your files so they are not as big and don't contain so many if statements (even if the total is still the same it's better structured and clearer)
For example instead of:
{{-- ... --}
</div>
#if ($summary['newSetup'] == false)
<div class="installation">
<h4>Phone Line x <span class="summary-lines">{{$summary['lines']}}</span></h4>
<ul class="clearfix">
<li>
<p class="installation-details">Installation</p>
<p class="installation-price">£{{$summary['installationCharge']}}</p>
</li>
</ul>
</div>
#endif
<div class="off-costs bg-gray">
<div class="off-costs-header clearfix">
{{-- ... --}}
Put the installation part in it's own file and include it:
{{-- ... --}
</div>
#if ($summary['newSetup'] == false)
#include('installation')
#endif
<div class="off-costs bg-gray">
<div class="off-costs-header clearfix">
{{-- ... --}}

Categories