How to limit the number of notifications in Laravel - php

I have tried the ->limit(4) methods, but that doesn't seem to work
#foreach(auth()->user()->unreadNotifications()->limit(4) as $notification)
<li>
<a href="profile.html">
<div>
{{ $notification->data['message'] }}<span class="pull-right text-muted small">{{ time_elapsed_string($notification->created_at) }}</span>
</div>
</a>
</li>
#endforeach

You do not execute the query here:
#foreach(auth()->user()->unreadNotifications()->take(4)->get() as $notification)
Also, you shouldn't run queries in Blade files.

It's hard to say what unreadNotifications really returns but if it's collection you could use:
#foreach(auth()->user()->unreadNotifications()->take(4) as $notification)
and if it's relationship you could use:
#foreach(auth()->user()->unreadNotifications()->take(4)->get() as $notification)

Try this one
foreach(\Auth::user()->unreadNotifications->take(1) as $data){echo $data->id;}

Related

Trying to use Laravel policies into components

I'm trying to use Policies inside a Post Component, using Laravel. This is how I'm iterating through the posts in my page.
#foreach($posts as $post)
<x-post
:id="$post->id"
:title="$post->title"
:description="$post->description"
:userId="$post->user_id"
:img="$post->img"
:author="$post->user->name"/>
#endforeach
In the post.blade.php I'm trying to use a 'update' policy method to define which users can see the post:
#can('update', Auth::user(), /*What shoud I pass here?*/)
<a class="btn btn-success"href="{{route('posts.edit', $id)}}">
<i class="bi bi-pencil"></i>
</a>
#endcan
What should I pass as the second parameter of the policy? Normally, it would be a post variable. Since I'm already inside a post, I don't know to proceed.
You could check outside the component. Something like
#foreach ($posts as $post)
<x-post
:id="$post->id"
:title="$post->title"
:description="$post->description"
:userId="$post->user_id"
:img="$post->img"
:author="$post->user->name"
:canUpdate="Auth::user()->can('update', $post)"/>
#endforeach
#if ($canUpdate)
<a class="btn btn-success"href="{{ route('posts.edit', $id) }}">
<i class="bi bi-pencil"></i>
</a>
#endif

How to use orWhere to combine results in Laravel?

I'm trying to find the slugs complete and incomplete model TaskboardColumn, then I only want the values of the user and the project.
Here is what I've tried:
Model
public static function projectOpenTasks($projectId, $userID=null)
{
$taskBoardColumn = \App\TaskboardColumn::where('slug', 'incomplete')->first();
$taskBoardColumn2 = \App\TaskboardColumn::where('slug', 'inprogress')->first();
$projectTask = \App\Task::where('tasks.board_column_id', $taskBoardColumn->id)->orWhere('tasks.board_column_id', $taskBoardColumn2->id);
if($userID)
{
$projectIssue = $projectTask->where('user_id', '=', $userID);
}
$projectIssue = $projectTask->where('project_id', $projectId)
->get();
return $projectIssue;
}
Controller
$this->openTasks = Task::projectOpenTasks($this->project->id);
View
<ul class="list-task list-group" data-role="tasklist">
<li class="list-group-item" data-role="task">
<strong>#lang('app.title')</strong>
<span class="pull-right"><strong>#lang('app.dueDate')</strong></span>
</li>
#forelse($openTasks as $key=>$task)
<li class="list-group-item row" data-role="task">
<div class="col-xs-8">
{{ ($key+1).'. '.ucfirst($task->heading) }}
</div>
<label class="label label-danger pull-right col-xs-4">{{ $task->due_date->format($global->date_format) }}</label>
</li>
#empty
<li class="list-group-item" data-role="task">
#lang('messages.noOpenTasks')
</li>
#endforelse
</ul>
With this code I'm getting all the tasks, and I need just this project's tasks.
You can use grouping to achieve this
$projectTask = \App\Task::where(function($q) {
$q->where('tasks.board_column_id', $taskBoardColumn->id);
$q->orWhere('tasks.board_column_id', $taskBoardColumn2->id)
})->get();
Thanks
orwhere is used in places where only one of the query has to run. just like and keyword in programming orwhere is used in sense of query.
following is the code snippet -
$projectTask = $query->where('tasks.board_column_id', $taskBoardColumn->id)
->orWhere('tasks.board_column_id', $taskBoardColumn2->id)
->get();

Undefined offset: 1 in CompilesLoops.php laravel 5

I have a services list. Now I want to add sub-services to services list. I have two tables 'services' and 'sub-services' with foreign key constraint 'service_id'. Now, I want to show the 'services' and related 'sub-services' in master.blade.php. For services it was working fine, but, when trying with sub-services then getting this error. Would someone please help to get the expected result.
In master.blade.php-
<li class="dropdown"> Services
<ul class="dropdown-menu services-dropdown" role="menu">
#forelse(App\Model\Service::all() as $service)
<li class="dropdown-submenu">
{{ $service->title }}
<ul class="dropdown-menu sub-services">
#foreach(App\Model\SubService::where('service_id', '=',$service->id)->get()) as $subservice)
<li>
{{ $subservice->title }}
</li>
#endforeach
</ul>
</li>
#empty
#endforelse
</ul>
</li>
Two tables are here-
1.Services table
2.Sub-services table
You're using the wrong syntax. You're using redundant ) near the get(), so change it to:
#foreach(App\Model\SubService::where('service_id', $service->id)->get() as $subservice)
Also, as I say in my best practices repo, you shouldn't execute queries in a Blade template. Consider moving the logic to a controller.
This error also occurs when you don't close you loop correctly.
Use #foreach() to start a loop and #endforeach to close the same loop.
Its a bad way to write a logic part in blade file.I would suggest you to move it to controller because if in case you need to change the code you have to edit blade page.As well as please make use of relationship for fetching the data you can relate your Service with SubService
E.g
Service.php (model file)
public function subServices()
{
return $this->hasMany('App\SubService');
}
SubService.php (model file)
public function services()
{
return $this->belongsTo('App\Service','service_id');
}
your blade code:
#forelse(App\Model\Service::all() as $service)
<li class="dropdown-submenu">
{{ $service->title }}
<ul class="dropdown-menu sub-services">
#foreach($service->subServices as $subservice)
<li>
{{ $subservice->title }}
</li>
#endforeach
</ul>
</li>
#empty
#endforelse

Laravel 5.3, Call to undefined method Illuminate\Database\Query\Builder::links()

I'm making an attemp to write advanced Eloquent search query filters but when I return the collection to view, I get the following error
Call to undefined method Illuminate\Database\Query\Builder::links()
My Eloquent query builder:
$catalogos = Catalogo::query();
$catalogos->where('catalogo.subcategoria',$filtro)
->join('productos', 'productos.catalogo_id','=','catalogo.id')
->join('productos_precios','productos_precios.segment','=','productos.codigo_oracle')
->join('fotos_productos','fotos_productos.producto_id','=','productos.id')
->select('catalogo.descripcion', 'catalogo.descripcion_corta','catalogo.id','fotos_productos.nombre as ruta', 'productos_precios.precio')
->whereNotNull('fotos_productos.nombre')
->orderBy('precio', 'asc')
->groupBy('catalogo.id')
->paginate(24);
And yes, if I dd($catalogos), it returns me a Builder instance, but why?
My view code is as follows (just in case you're thinking I'm overwriting the value of the $catalogos variable):
#foreach($catalogos as $catalogo)
<div class="producto_tienda">
<a href="{{route('detalle-producto', [$catalogo->id,$catalogo->slug] ) }}">
<div class="foto_producto" style="background-image:url('{{ asset("public/images/tienda/".$catalogo->ruta) }}')">
#if($catalogo->stock>0 && $catalogo->stock<10)
<div class="etiquetas">
<p class="existencia">Últimos productos</p>
</div>
#endif
#if($catalogo->stock==0)
<div class="etiquetas">
<p class="descuento">Agotado</p>
</div>
#endif
</div>
</a>
<a href="{{route('detalle-producto', [$catalogo->id,$catalogo->slug])}}">
<div class="descripcion_producto">{{ $catalogo->descripcion_corta }}</div>
</a>
<div class="precio_producto">{{ money_format( '%.2n' ,$catalogo->precio) }}</div>
</div>
#endforeach
<div class="text-center">
{{ $catalogos->links() }}
</div>
You are not assigning the return value of paginate to anything. It should be:
$catalogos = Catalogo::query()->where('catalogo.subcategoria',$filtro)
->join('productos', 'productos.catalogo_id','=','catalogo.id')
->join('productos_precios','productos_precios.segment','=','productos.codigo_oracle')
->join('fotos_productos','fotos_productos.producto_id','=','productos.id')
->select('catalogo.descripcion', 'catalogo.descripcion_corta','catalogo.id','fotos_productos.nombre as ruta', 'productos_precios.precio')
->whereNotNull('fotos_productos.nombre')
->orderBy('precio', 'asc')
->groupBy('catalogo.id')
->paginate(24);
Now it appears to be working with this:
$catalogos = Catalogo::query();
$catalogos = $catalogos->where('catalogo.subcategoria',$filtro)
->join('productos', 'productos.catalogo_id','=','catalogo.id')
->join('productos_precios','productos_precios.segment','=','productos.codigo_oracle')
->join('fotos_productos','fotos_productos.producto_id','=','productos.id')
->select('catalogo.descripcion', 'catalogo.descripcion_corta','catalogo.id','fotos_productos.nombre as ruta', 'productos_precios.precio')
->whereNotNull('fotos_productos.nombre')
->orderBy('precio', 'asc')
->groupBy('catalogo.id')
->paginate(24);
From the docs:
Currently, pagination operations that use a groupBy statement cannot be executed efficiently by Laravel. If you need to use a groupBy with a paginated result set, it is recommended that you query the database and create a paginator manually.
You should follow the documentation and create a manual paginator for your query.
https://laravel.com/docs/5.4/pagination#manually-creating-a-paginator

Included blade template repeating in each foreach loop iteration

I'm using Blade templating with Laravel and I'm trying to use a #foreach loop to display notifications. The problem is that if I have say 10 notifications, the first notification is repeated 10 times.
The code to output each notification:
#foreach ( Auth::user()->unreadNotifications as $notification )
{{ $notification->type->web_template }}
{{ $notification->id }}
#include($notification->type->web_template)
#endforeach
web_template will output a path to the template: notifications.web.user_alert
For each iteration of the loop the {{ $notification->type->web_template }} and {{ $notification->id }} will output what they're supposed to but #include($notification->type->web_template) will only output the first notification each time.
So the output will look like:
156 notification.web.new_message
You have a new message from Joe.
154 notification.web.user_alert
You have a new message from Joe.
145 notification.web.new_like
You have a new message from Joe.
I think it's some sort of cache issue maybe, but I couldn't find anyone with the same problem.
Any ideas?
UPDATE: Adding some code
Example notification view:
#extends('layouts.notification-wrapper')
#section('url', url('jobs/'.$notification->job_id.'#highlight'.$notification->bid_id))
#section('image', '/assets/img/no-photo.jpg')
#section('header', $notification->collector->firstname . ' ' . $notification->collector->secondname)
#section('description')
has placed a bid of €{{ number_format($notification->bid()->withTrashed()->first()->amount,0) }} on your job.
#stop
Notification wrapper:
<li #if(!$notification->read)
class="unread"
#endif>
<a href="#yield('url')" data-id="{{ $notification->id }}">
<div class="pull-left">
<img src="#yield('image')" class="img-circle" alt="user image">
</div>
<h4>
#yield('header')
<small><i class="fa fa-clock-o"></i> {{ $notification->created_at->diffForHumans()}}</small>
</h4>
<p> #yield('description')</p>
</a>
</li>
Answering my own question!
Found this: Laravel Blade Templates Section Repeated / cache error
Basically whatever way it works I need to overwrite my sections when looping and using #yield... I think. So I need to replace #stop with #overwrite in my views.

Categories