Display content for user and for admin - laravel

I would like that normal users don't see the pictures with a status of 0 (not visible) only the visible ones (status 1) but that admins can see everything.
Is this kind of solution viable or is there something cleaner to do?
The gates/policies are not adapted for that, I don't see any other solution to my knowledge, that's why I come to you
Thanks in advance
public function show($name)
{
if(Auth::user()->isAdmin()) {
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->with('pictures')->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
} else {
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->with('visible_pictures')->first();
});
$pictures = $model->visible_pictures()->latest()->paginate(18);
}
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}

You can clean it up by using when function in the query itself.
public function show($name)
{
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->when( Auth::user()->isAdmin() , function ($q)
{
return $q->with('pictures');
}, function ($q)
{
return $q->with('visible_pictures');
})->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}
or we could also use arrow functions
public function show($name)
{
$model = cache()->remember('model_show'.$name, Config::get('cache.ttl'), function() use ($name) {
return Model::where('name', $name)->when( Auth::user()->isAdmin() ,
fn($q) => $q->with('pictures') ,
fn($q) => $q->with('visible_pictures')
)->first();
});
$pictures = $model->pictures()->latest()->paginate(18);
return view('model.model')->with(['model' => $model, 'pictures' => $pictures]);
}

Related

Laravel Inertia prop not passing values

When calling an edit function the prop mealService is passing null values and will not populate form fields with values. It looks like the controller isn't loading the model to query the single record. The Create and Store functions work fine.
First time posting. And very new to coding. Please let me know if more info is needed for the question.
edit.vue
export default {
components: {
Head,
Link,
LoadingButton,
SelectInput,
TrashedMessage,
},
layout: Layout,
props: {
mealService: Object,
sites: Array,
},
remember: 'form',
data() {
return {
form: this.$inertia.form({
site_id: this.mealService.site_id,
meal_type: this.mealService.meal_type,
adults: this.mealService.adults,
tally: this.mealService.tally,
}),
}
},
MealServiceController
public function edit(MealService $meal_service)
{
return Inertia::render('MealServices/Edit', [
'mealService' => [
'id' => $meal_service->id,
'site_id' => $meal_service->site_id,
'meal_type' => $meal_service->meal_type,
'adults' => $meal_service->adults,
'tally' => $meal_service->tally,
],
'sites' => Auth::user()->sfa
->sites()
->orderBy('name')
->get()
->map
->only('id', 'name'),
]);
}
MealService Model
class MealService extends Model
{
use HasFactory;
use SoftDeletes;
public function resolveRouteBinding($value, $field = null)
{
return $this->where($field ?? 'id', $value)->withTrashed()->firstOrFail();
}
public function site()
{
return $this->belongsTo(Site::class);
}
public function scopeFilter($query, array $filters)
{
$query->when($filters['search'] ?? null, function ($query, $search) {
$query->WhereHas('site', function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
});
})->when($filters['trashed'] ?? null, function ($query, $trashed) {
if ($trashed === 'with') {
$query->withTrashed();
} elseif ($trashed === 'only') {
$query->onlyTrashed();
}
});
}
}
Route
Route::get('mealServices/{mealService}/edit', [MealServicesController::class, 'edit'])
->name('mealServices.edit')
->middleware('auth');
In your edit function you are using meal_service while in your route you use mealService
Try naming the one in the edit function mealService too

How to return from execution stack immediately as value is found

I have search functionality. If a user wants to find anothers' threads, it comes in as a boolean TRUE.
I am able to dd($threads) in its execution stack, but it seems like it follows through with the rest of the execution stack.
For example:
public function scopeSearch(Builder $query, ?string $search = null, ?array $users = null, ?bool $title = null, ?bool $threads = null)
{
if ($threads == TRUE) {
return $query->whereHas('thread', function ($query) use ($users) { return $query->whereIn('threads.user_id', $users)->toSql(); });
}
elseif (!$search) {
return $query->when($users, function ($q) use ($users) { $q->whereIn('user_id', $users)
->whereHas('thread', function ($query) use ($users) { $query->whereIn('threads.user_id', $users); })
->orWhereHas('reply', function ($query) use ($users) { $query->whereIn('replies.user_id', $users); })
->orWhereHas('product', function ($query) use ($users) { $query->whereIn('products.user_id', $users); })
->orWhereHas('review', function ($query) use ($users) { $query->whereIn('reviews.user_id', $users); })
;
});
}
}
I can dd($threads), but want to know how I can stop it right there, as it's not returning the toSql statement, and, I want it to just return the threads.
Any help is appreciated :) thanks all :).
In my controller method:
I had:
if ($threads) {
}
if (!empty($variable) {
}
It should have been "paired together" like such
if ($threads) {
} elseif (!empty($variable)) {
} elseif (etc, etc) {
}

want to update array values in vuejs using laravel

i have an array values in update form. i need to update specific values when user change in textareas. it looks like this
In my vuejs data objects looks like this.
data() {
return {
jobs: [],
details: {
basic_id: this.$route.params.id,
work: this.jobs
}
};
},
and my update method i wrote like this.
updateDetails() {
this.loading = true;
this.updateWorkedPlaces(this.details)
.then(() => {
console.log("success");
this.loading = false;
})
.catch(() => {
this.loading = false;
});
}
i pass these values it my vuex action methods.
async updateWorkedPlaces({ commit }, payload) {
let job = await Api().put("works/" + payload.basic_id, payload.work);
commit("UPDATE_WORK", job);
},
i pass these values to my laravel backend update function. it looks like this.
public function update(Request $request, $id)
{
$work = $request->work;
$basic = $request->basic_id;
foreach ($request->work as $i => $id) {
$job = Job::findOrFail($basic);
$job->fill(['position' => $id['position'], 'address' => $id['address']])->save();
}
return response()->json(['message' => 'success']);
}
but when i pass these values to this function it shows me this error.
Invalid argument supplied for foreach()
how can i fix this error. anyone can help me?
i figure out my problem with this function
public function update(Request $request, $id)
{
$collection = $request->all();
for ($i = 0; $i < count($collection); $i++) {
Job::where('id', $collection[$i]['id'])
->update([
'position' => $collection[$i]['position'],
'address' => $collection[$i]['address']
]);
}
return response()->json(['collection' => $collection]);
}

Laravel paginate view don't see

I'm trying to do paginate in my view. I have reaaalyy alot of products, but I want only 12 per page. This is my controller:
public function index(Request $request)
{
$products = Product::paginate(12);
if ($request->has('colorValue')) {
$products->whereHas('productColors', function ($query) use ($request) {
$query->whereIn('id', $request->colorValue);
});
}
if ($request->has('heelValue')) {
$products->whereHas('productHeelTypes', function ($query) use ($request) {
$query->whereIn('id', $request->heelValue);
});
}
if ($request->has('materialValue')) {
$products->whereHas('productColors', function ($query) use ($request) {
$query->whereIn('id', $request->materialValue);
});
}
if ($request->has('maxPrice')) {
if($request->maxPrice > 0){
$products->where('sell_price_gross', '<=', $request->maxPrice);
}
}
$colors = ProductColor::all();
$heels = ProductHeelType::all();
$materials = ProductMaterial::all();
return view('product-list', ['products' => $products->get(), 'colors' => $colors, 'heels' => $heels, 'materials' => $materials]);
}
}
Now I'm trying to render it in my view:
<div class="paginate">
{{$products->render()}}
</div>
But I have error:
Type error: Too few arguments to function
Illuminate\Support\Collection::get(), 0 passed in /home/ania/Dokumenty/Projekty/viola-kiosk/vendor/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php on line 568 and at least 1 expected
What is wrong??
I think you can try this change your return view code like:
return view(
'product-list',
['products' => $products, 'colors' => $colors, 'heels' => $heels, 'materials' => $materials]
);

Route issue: URL doesn't change

I've created a page to edit a message, I can edit my message and save in my database. After the save, I return View::make("messages.index");
But if I look at the URL, it is: http://localhost:8000/update/42 instead of http://localhost:8000/messages
Did I do something wrong? (I assume I made a mistake in my routes.php, but I can't find it)
Routes:
Route::get('/', array('as' => '/', function()
{
return View::make('index');
}));
Route::get("Messages", function()
{
return View::make("Messages.index");
});
Route::resource('messages', 'MessageController');
Route::post('messages/{messages}', 'MessageController#destroy');
Route::put('update/{messages}', array('as' => 'putMessage', 'uses' => 'MessageController#update'));
Route::get('messages/{messages}/edit', array('as' => 'editMessage', 'uses' => 'MessageController#edit'));
Route::post('messages', array('as' => 'storeMessage', 'uses' => 'MessageController#store'));
MessageController:
<?php
class MessageController extends \BaseController {
public function index()
{
$messages = Message::join('tblMessages_tblTeams', 'tblMessages.PK_message', '=', 'tblMessages_tblTeams.FK_message')
->join('tblTeams', 'tblMessages_tblTeams.FK_team', '=', 'tblTeams.PK_team')
->where('PK_team', 1)
->orderBy('created_at', 'DESC')
->get();
return View::make("messages.index")->withMessages($messages);
}
public function create()
{
//
}
// HARD CODED WILL BE REPLACED WHEN ABLE TO LOG IN
// FK_user => Auth::id()->FK_team
public function store()
{
$date = new DateTime;
// INSERT IN DATABASE
$message = new Message;
$message->FK_user = 1;
$message->priority = Input::get("messagePriority");
$message->title = Input::get('messageTitle');
$message->content = Input::get('messageContent');
$message->visible = true;
$message->showFrom = Input::get('messageShowFrom');
$message->removeFrom = Input::get('messageHideFrom');
$message->created_at = $date;
$message->updated_at = $date;
$message->save();
$message->teams()->attach(array(1,3));
return Redirect::back();
}
public function show($id)
{
$deleteMessage = Message::findOrFail($id);
$deleteMessage->visible = 0;
$deleteMessage->save();
return Redirect::back();
}
public function edit($id)
{
$message = Message::findOrFail($id);
$showFrom = $message->showFrom;
$removeFrom = $message->removeFrom;
$showFrom = str_replace(' 00:00:00', '', $showFrom);
$removeFrom = str_replace(' 00:00:00', '', $removeFrom);
return View::make('messages.index')
->withMessage($message)
->with("showFrom", $showFrom)
->with("removeFrom", $removeFrom);
}
public function update($id)
{
$date = new DateTime;
$editMessage = Message::findOrFail($id);
$editMessage->FK_user = 1;
$editMessage->priority = Input::get("messagePriority");
$editMessage->title = Input::get('messageTitle');
$editMessage->content = Input::get('messageContent');
$editMessage->visible = true;
$editMessage->showFrom = Input::get('messageShowFrom');
$editMessage->removeFrom = Input::get('messageHideFrom');
$editMessage->updated_at = $date;
$editMessage->save();
return View::make("messages.index");
}
public function delete($id)
{
//
}
public function destroy($id)
{
dd('destroy');
}
}
What you are returning here, is the page /app/views/Messages/index.php
return View::make("Messages.index");
If you want to call another route, you should use:
Redirect::route('messages');
That is the way it works because your form has been submitted to update/42.
You can return by redirecting like below to have the URL you want the user to be at.
return Redirect::to('/Messages');
and if you want to carry any values to that view you can use
->withInput();
Also refer this for more information

Resources