Laravel - Authorize with other policy - laravel

I have a gallery policy and a photo policy, a gallery controller, and a photo controller.
It works like this:
user-> hasMany galleries -> hasMany photos
I do have a photo upload page (with dropzone), that uses the photo controller.
the url is like this: /gallery/3/upload
I want to restrict access to this page only if the user is the owner of the gallery 3. But this page uses the PhotoPolicy, that makes use of the Photo model, not the Gallery model.
How can I authorize this page, using the GalleryPolicy instead of the PhotoPolicy? Or do I have to copy over the view method from the GalleryPolicy and have it also in the PhotoPolicy?
EDIT:
I do not understand this...
In my PhotoPolicy:
public function view(User $user, Photo $photo)
{
return false;
}
In my Photos controller:
$this->authorize('view', $photo);
In my AuthenticationServiceProvider:
protected $policies = [
\App\Gallery::class => \App\Policies\GalleryPolicy::class,
\App\Photo::class => \App\Policies\PhotoPolicy::class,
];
Restult: page loads just fine.. even if return is false.. why?

You can authorize this page in PhotoPolicy in create method, because you have just one way to upload images which is also using this url.
In PhotoPolicy you have gallery's id which it was passed as params, so you can check owner of gallery and restrict them.
And another point is according to API rules it's better change upload's url to gallery/3/photos.

Related

how to display data based on specific id in laravel?

I am new to laravel. I want to send data as id of existing data. Id comes from products.blade I send via href tag as shown below to gallery page. I have tried to find a way through other sites but it still doesn't work
<a class="btn btn-success" href="/dashboard/galleries/{{ $product->id }}"><i class="ri-image-add-line text-white"></i></a>
then i create a route like this
Route::resource('/dashboard/galleries', DashboardGalleryController::class)->middleware('admin')->shallow();
in the controller gallery, I made like this
public function index($id)
{
$gallery = Gallery::where('products_id', $id)->get();
return view('dashboard.galleries.index', compact('gallery'));
}
then inside the gallery page, I want to display a table to add images based on that id.
dashboard/galleries/index.blade.php
<h1>{{ $gallery->id }}</h1>
should i add data inside foreach or outside?
A restful resource controller sets up some default routes for you and even names them.
and ur case the logic should be inside show() function not index()
check this issue it will help u same issue solved here

Laravel 9 how to redirect to a custom route after registration in laravel jetstream

I'm using Laravel Jetstream and Laravel 9 for user login and registration. I have also implemented email verification after registration and it works fine.
The problem comes when I want to display a new page called "news" instead of "dashboard" after login and registration. After user login the "news" page is displayed correctly, but after registration of a new users it sends me directly to the news page and not to the email verification page.
How can I show the email verification page when a new user registers and only after he verifies his email, the "news" page appears?
I made this changes to show the news page :
In app/Providers/RouteServiceProviver file changed this line:
public const HOME = '/dashboard';
To this:
public const HOME = '/news';
In the web.php file I added this line to show the route
Route::get('news', [CustomViewController::class, 'showNews'])->middleware('auth')->name('news');
And the showNews function in the controller is:
public function showNews(){
$user = auth()->user()->name;
return view('newviews.news' ,compact('user'));
}
And the view is this:
<x-app-layout>
Welcome {{$user}}
</x-app-layout>
Check the config file of fortify.php what is the value of the equal home,
When the user is authenticated, it will be redirected to that value.

how can i make 4 links to a controller?

i'm setting up a new project in my laravel
The stuffs i have :
1- PostsController
2- Post model
3- Routes:resource('posts','PostsController')
4- after i login i have a create button for post create
after click on it i have below image :
My desire:
i want without changing whole project or whole routes resources have these :
after i login i want to have 4 boxes like this( i made it )
with this property :
after i click any of them i can create post according to their type
for example if i click on video content i enter to a page with 2 form:
like title video and upload video
after i click on text content i enter to page like the image i showed
you at the first
it means if i click on video content, resource route take me to create method in postscontroller and create method check if i came from content video link
return view (posts.create_video) or if i came from sound content link box return view(posts.content_sound) and etc boxes
how can i do all of that please help me thanks
You could structure it as following:
[routes/web.php]
Route::get('posts/create/{type}', 'PostController#create')->name('posts.create');
Route::resource('posts', 'PostController')->except(['create']);
[PostController]
class PostController extends Controller
{
public function create($type)
{
if (in_array($type, ['sound', 'video', 'image', 'text'])) {
return view("posts.content_{$type}");
}
abort(404);
}
}

Laravel 5.6 Like Button

I'm using this package here in Laravel 5.6 to add likes system in my project.
I have updated the models as per their documentation. However, I'm confused on how to use this package.
I have added tried the following which adds the logged in user to the particular article likes list when he visits the link.
public function show(ArticleCategory $articlecategory, $slug)
{
$categories = ArticleCategory::all();
$article = Article::where('slug', $slug)->first();
$user = User::first();
$user->addFavorite($article);
return view('articles.show', compact('article', 'categories'));
}
And in my user dashboard, I'm able to pull up all the articles which are liked by the user with
$user = Auth::user();
$favoritearticles = $user->favorite(Article::class);
But I'm looking for a functionality where I have a button on the article page where when a logged user clicks on it, he is added to the likes list. I haven't tried this before so stuck at this point.
I replaced
$user->addFavorite($article);
with
$user->toggleFavorite($article);
but that just toggles the favourite list. I mean when I visit the link once, the logged in user is added to the likes list. When I visit the link for the second time, the logged in user is removed from the likes list. The cycle is repeated.
Could anyone explain to me how to achieve the like functionality with a button?
you're almost there,
You have to add a button and on click you will trigger an AJAX request to the server to perform what you want without refreshing the page, here is an example:
First you'll add a button and give it an ID or class:
<button class="like">Like</button>
Then the moment you click on it, you'll call the url which you need to replace with the route to your function,
Then you have to declare a method like so:
public function like($slug)
{
$article = Article::where('slug', $slug)->first();
$user = \Auth::user(); //to get authenticated user...
$user->toggleFavorite($article); // toggle so if u already like it u remove it from the liked table
return response()->json(['status': 1])
}
And of course add the route to your routes.php:
Router::get('like/{slug}',"ArticleController#like");
then add the function (jQuery is used here) to hook the AJAX call
$('.like').on('click', function(){
$.ajax({
type: "GET",
url: 'wwww.example.com/articles/slug',
data: {slug: 'the slug'},
success: function(data){
alert('its done')
},
});
})
Create a form in you article page with a button
<form action="{{url('favorite/{$post->id}')}}" method="post">
#if($post->isFavorited())
<button type="submit">Remove from favorite</button>
#else
<button type="submit">Add to favorite</button>
#endif
</form>
create the favorite route and controller
Router::post('favorite/{id}',"ArticleController#toggleFavorite");
public function toggleFavorite($id) {
$article = ArticleCategory::find($id);//get the article based on the id
Auth::user()->toggleFavorite($article);//add/remove the user from the favorite list
return Redirect::to('article/{$id}');//redirect back (optionally with a message)
}

How to send data from different controllers/actions to the same view?

This is my first experience with Laravel, and so far I'm having some difficulties passing data to views. My app is a single page website with one menu on the top listing all the product categories and below there is a grid of thumbnails for each item or product. Visitors are able to filter the products by their category of choice.
Route::get('home/{category}', array('as'=>'itemshome', 'uses'=>'ItemsController#index'));
So in my ItemsControllers I fetch some items from the item model and pass them to the view.
class ItemsController extends \BaseController {
public function index($category)
{
return View::make('home/index', ['items' => Item::where('publishtime', '<',
date('Y-m-d H:i:s'))->where('category_id','=',$category)->paginate(24)]);
}
At this point I'm not sure if I should send data from the Category model to the home view using the ItemsController, or if it would it be a better approach to define a new CategoryController and pass the values from there.
You can't just use another controller to send data to the same view during the same request.
Either add it to the view make call:
return View::make('home/index', [
'items' => Item::where('publishtime', '<', date('Y-m-d H:i:s'))->where('category_id','=',$category)->paginate(24),
'categories' => Category::all()
];
Or, if the category data actually has nothing to do with the items controller but is needed by the view, you could register a view composer
View::composer('home/index', function($view){
$view->with('categories', Category::all());
});
Now every time when the home/index view gets rendered, categories will be injected.
You can actually place the view composer anywhere you want. However I recommend you add a new file app/composers.php to store all your view composers. Then you need to include it somewhere. For example in app/start/global.php at the bottom:
require app_path().'/composers.php';

Resources