Fetch relationship with respective to relationship data in Laravel 5.7 - laravel

Let me give you a basic overview:
There is an app where people will register their pets and would report when a pet is lost. Also, people who have seen a lost pet would report a sighting for the pet so that the owner of the pet would be notified and he could retrieve his pet.
I have five models:-
Color Model
class Color extends Model
{
public function colorPet()
{
return $this->hasMany('App\Models\Pet');
}
}
Breed Model
class Breed extends Model
{
public function breedPetType()
{
return $this->belongsTo('App\Models\PetType', 'pet_type_id');
}
public function breedPet()
{
return $this->hasMany('App\Models\Pet');
}
}
Pet Type Model
class PetType extends Model
{
public function petTypeBreed()
{
return $this->hasMany('App\Models\Breed');
}
}
Pet Model
class Pet extends Model
{
public function petBreed()
{
return $this->belongsTo('App\Models\Breed', 'breed_id');
}
public function petPetType()
{
return $this->belongsTo('App\Models\PetType', 'pet_type_id');
}
public function petColor()
{
return $this->belongsTo('App\Models\Color', 'color_id');
}
public function petUser()
{
return $this->belongsTo('App\User', 'user_id');
}
}
Lost Report
class LostReport extends Model
{
public function lostReportPet()
{
return $this->belongsTo('App\Models\Pet', 'pet_id');
}
public function lostReportUser()
{
return $this->belongsTo('App\User', 'user_id');
}
public function lostReportPetSighting()
{
return $this->hasMany('App\Models\PetSighting', 'lost_report_id');
}
}
Pet Sighting
class PetSighting extends Model
{
public function petSightingLostReport()
{
return $this->belongsTo('App\Models\LostReport', 'lost_report_id');
}
}
Here is ny query:-
$petSightingRadiusQueryString = "( $unitDistance * acos( cos( radians($latitude) ) * cos( radians( pet_sightings.latitude ) )
* cos( radians( pet_sightings.longitude ) - radians($longitude) ) + sin( radians($latitude) ) * sin(radians(pet_sightings.latitude)) ) )";
$lostPetQuery = LostReport::with('lostReportPet')
->where(array(
'lost_reports.is_found' => Globals::SMALL_CHAR_NO))
->whereHas('lostReportPet', function($queryReportPet) {
$queryReportPet->where(array(
'pets.status' => Globals::SMALL_CHAR_ACTIVE,
'pets.is_delete' => Globals::SMALL_CHAR_NO,
'pets.is_lost' => Globals::SMALL_CHAR_YES
));
});
$lostPetQuery = $lostPetQuery->where(function($orQuery) use($userId, $petTypeArrayForLostPet, $lostPetRadiusQueryString, $lostPetRadius, $petSightingRadiusQueryString, $petSightingRadius){
$orQuery->where('lost_reports.user_id', $userId) // where the post report is by owner
->orWhere(function($lostPetNotificationQuery) use($petTypeArrayForLostPet, $lostPetRadiusQueryString, $lostPetRadius){
$lostPetNotificationQuery->whereIn('pets.pet_type_id', $petTypeArrayForLostPet)
->whereRaw($lostPetRadiusQueryString . ' < ' . $lostPetRadius);
}) // where the lost report is of same pet type
->orWhereHas('lostReportPetSighting', function($petSightingNotificationQuery) use ($petSightingRadiusQueryString, $petSightingRadius){
$petSightingNotificationQuery->whereRaw("pet_sightings.id = (SELECT MAX(pet_sightings.id) FROM pet_sightings WHERE pet_sightings.lost_report_id = lost_reports.id) AND " . $petSightingRadiusQueryString . " < " . $petSightingRadius);
}); // where pet sighting is enabled
});
Here is the result I am getting:-
Array
(
[id] => 1
[pet_id] => 3
[user_id] => 2
[phone] => 6290453837
[latitude] => 22.572645
[longitude] => 88.363892
[missing_date] => 2020-03-03 00:00:00
[found_date] =>
[is_found] => n
[is_delete] => n
[created_date] => 2020-03-03 15:08:03
[modified_date] => 2020-03-03 15:08:03
[created_at] => 2020-03-03 15:08:03
[updated_at] => 2020-03-03 15:08:03
[lost_report_pet] => Array
(
[id] => 3
[name] => Micky
[image] => p-1583228283-3.jpg
[pet_type_id] => 1
[breed_id] => 1
[color_id] => 1
[age] => 2
[weight] => 7
[description] => Very cute doggo
[is_approachable] => y
[user_id] => 2
[status] => a
[is_delete] => n
[is_lost] => y
[created_date] => 2020-03-03 15:08:03
[modified_date] => 2020-03-03 15:08:03
[created_at] => 2020-03-03 15:08:03
[updated_at] => 2020-03-03 15:08:03
)
)
As you can see, the relationship 'lost_report_pet'. How can I get the breed, color and pet_type relationship from lost_report_pet?

I'm pretty sure you could try with the relationship dot notation:
LostReport::with([
'lostReportPet.petBreed',
'lostReportPet.petPetType',
'lostReportPet.petColor'
]);

Related

laravel how to add price product variations in laravel cart session

this is taking more than i anticipated,
On my shopping cart app i'm able to add product to app cart session with no problem, But now i need to add product variations like (color, size, ... etc) for every product added to the cart, These variation can change to product price according to users selection on product details page.
The code that i have currently is working for me except that i can't add a list of variation for a single product i can only create one variation then the code is replacing it with new variation value.
This is my cart object when running {{print_r($cart)}}
App\Cart Object
(
[items] => Array
(
[27] => Array
(
[id] => 27
[name] => product with variation and colors
[slug] => iphone-pro13
[price] => 100
[prefix] => QAR
[qty] => 1
[poster] => /image/md/9964677a-c957-4510-9eb4-f41578c069b3
[subtotal] => 730
[quotable] => 0
[variations] => Array // these are the list of product variations
(
[16] => Array
(
[id] => 16
[var_name] => This is the variation
[var_price] => 365.00
[var_qty] => 1
[var_subtotal] => 365
[color_code] => #e6bf00
)
)
)
[12] => Array
(
[id] => 12
[name] => Dolore quis sunt reiciendis.
[slug] => iste-autem-beatae-eaque-natus-distinctio
[price] => 96.08
[prefix] => QAR
[qty] => 1
[poster] => /media/default/product-placeholder.jpg
[subtotal] => 350.692
[quotable] => 0
[variations] => Array // these are the list of product variations
(
[0] => Array
(
[var_name] => This is the variation 2
[var_price] => 335.00
[var_qty] => 1
[var_subtotal] => 365
[color_code] => #e6bf00
)
)
)
)
the is my cart.php class
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Cart extends Model
{
public $items = null;
public $itemsCount = 0;
public $grandTotal = 0;
public $variations = null;
public function __Construct($oldCart = null) {
if($oldCart) {
$this->items = $oldCart->items;
$this->itemsCount = $oldCart->itemsCount;
$this->grandTotal = $oldCart->grandTotal;
$this->variations = $oldCart->variations;
}
}
public function add($product) {
if (isset($this->items)) {
if( array_key_exists($product->id, $this->items) ) {
$qty = $this->items[$product->id]['qty'] += $product->qty;
$subtotal = $qty * $product->price;
}else{
$qty = $product->qty;
$subtotal = $product->subtotal;
}
}else{
$qty = $product->qty;
$subtotal = $product->subtotal;
}
$item = [
'id' => $product->id,
'name' => $product->name,
'slug' => $product->slug,
'price' => $product->price,
'prefix' => $product->prefix,
'qty' => $qty,
'poster' => $product->poster,
'subtotal' => $subtotal,
'quotable' => $product->quotable,
];
$variations = [
'id' => $product->variation_id,
'var_name' => $product->variation,
'var_price' => $product->variation_price,
'var_qty' => $qty,
'var_subtotal' => $qty * $product->variation_price,
'color_code' => $product->color,
];
$this->items[$product->id] = $item; // <-- this adds new product
$this->items[$product->id]['variations'][$product->variation_id] = $variations; // <-- this adds new product variation
$this->itemsCount +=1;
$this->grandTotal += $product->price * $product->qty;
}
}
Not sure where my code went wrong but i need to be able to add list of product variations instead of replacing current ones.
any ideas?

Import CSV file, remove empty rows and export it immediately without storing it into database - laravel excel

I am trying to remove all the empty rows from a csv and make it downloadable. In this process, there is no involvement of database/model.
My flow looks like:
1) Import csv file.
2) Filter empty rows.
3) Export the data after all the empty rows are removed.
My code looks like:
Controller
public function formatCSV()
{
$path = storage_path('app/files/') . 'example.csv';
Excel::import(new FormatCSV, $path);
}
app/Imports/FormatCSV
<?php
namespace App\Imports;
use App\Exports\ExportFormattedCSV;
use App\Http\Services\AmenityService;
use Maatwebsite\Excel\Concerns\ToArray;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Excel;
class FormatCSV implements ToArray, WithChunkReading
{
private $table,$service,$model;
public function __construct()
{
$this->service = new AmenityService();
}
public function array(Array $rows)
{ $rec_arr = array();
foreach ($rows as $row)
{
$rec_arr[] = array_values($row);
}
$records_arr = $this->service->trimArray($rec_arr);
$export = new ExportFormattedCSV($records_arr);
//print_r($export);
return Excel::download($export, 'csv.csv');
}
public function chunkSize(): int
{
return 10;
}
}
trimArray function
public function trimArray($arr)
{
$final = array();
foreach($arr as $k => $v)
{
if(array_filter($v)) {
$final[] = $v;
}
}
return $final;
}
app/Exports/ExportFormattedCSV
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
class ExportFormattedCSV implements FromArray
{
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function array(): array
{
return $this->data;
}
}
With this code it does nothing, shows blank at the end.
However, if I uncomment the line print_r($export)
It shows data as:
App\Exports\ExportFormattedCSV Object
(
[data:protected] => Array
(
[0] => Array
(
[0] => First Name
[1] => Last Name
[2] => Roll No
)
[1] => Array
(
[0] => Ram
[1] => Patel
[2] => 1
)
[2] => Array
(
[0] => Rajuv
[1] => Roy
[2] => 2
)
[3] => Array
(
[0] => Sunny
[1] => Deol
[2] => 5
)
[4] => Array
(
[0] => Akshya
[1] => Kumar
[2] => 6
)
[5] => Array
(
[0] => Amir Khan
[1] => 7
[2] =>
)
[6] => Array
(
[0] => Salman
[1] => Khan
[2] => 9
)
[7] => Array
(
[0] => Bobby
[1] => Deol
[2] => 10
)
)
)
The File I am testing is example.csv
First Name,Last Name, Roll No
Ram,Patel,1
Rajuv,Roy,2
,,
Sunny,Deol,5
Akshya,Kumar,6
Amir Khan,7
,,
Salman,Khan,9
Bobby,Deol,10,
Barun,Dhawan,11
,,
Virat,Kohli,13
Rohit,Sharma,14

How can get the value from the third table in laravel and order by with id in descending order

In controller i have a code like this :
public function index(Request $request)
{
$course=Student::with('StudentDetail')->get();
$courses=$course->toArray();
echo "<pre>";print_r($courses);exit;
return view('student.student_listing',['result'=>$courses]);
}
through this i am getting result like :
Array
(
[0] => Array
(
[id] => 1
[name] => Neha
[email] => neha#sob.com
[roll_no] => 101
[created_at] => 2018-05-22 09:20:18
[updated_at] => 2018-05-22 00:00:00
[student_detail] => Array
(
[id] => 1
[student_id] => 1
[phone] => 11691110876
[course] => Java
[city] => Goa
[state] => 1
[created_at] => 2018-05-22 16:48:36
[updated_at] => 2018-05-22 09:20:43
)
)
[1] => Array
(
[id] => 2
[name] => Ankit
[email] => Ankit#sbo.com
[roll_no] => 102
[created_at] => 2018-05-22 09:20:18
[updated_at] => 2018-05-22 00:00:00
[student_detail] => Array
(
[id] => 2
[student_id] => 2
[phone] => 12313311
[course] => Phps
[city] => Delhi
[state] => 2
[created_at] => 2018-05-23 13:28:19
[updated_at] => 2018-05-15 03:15:13
)
)
)
Here i am getting a field state where i am getting the id this id
related to the states table id how can i get the value from states
table bassed on this id and i want this result in Descending order
with name or id how can i do that can anyone please help me related
this .
models i have like :
StudentDetail Model:
<?php
namespace App\Http\Model;
use Illuminate\Database\Eloquent\Model;
use App\Http\Model\Student;
use App\Http\Model\State;
class StudentDetail extends Model
{
public function Student()
{
return $this->belongsTo(Student::class);
}
public function state()
{
return $this->hasOne(State::class);
}
}
Student model:
<?php
namespace App\Http\Model;
use Illuminate\Database\Eloquent\Model;
use App\Http\Model\StudentDetail;
class Student extends Model
{
public function StudentDetail()
{
return $this->hasOne(StudentDetail::class);
}
}
You can use nested with()
public function index(Request $request)
{
$course=Student::with(['StudentDetail' => function($query){
$query->with('state);
}])->get();
$courses=$course->orderBy('studentDetail.state');
echo "<pre>";print_r($courses);exit;
return view('student.student_listing',['result'=>$courses]);
}
Or you can simply get using.
public function index(Request $request)
{
$course=Student::with('StudentDetail.state')->get();;
$courses=$course->orderBy('studentDetail.state');;
echo "<pre>";print_r($courses);exit;
return view('student.student_listing',['result'=>$courses]);
}

Laravel : Using transformers return error League\\Fractal\\TransformerAbstract

I am trying to return response data with transformers but it returns an error
Type error: Argument 2 passed to App\Support\Response::collection() must be an instance of League\Fractal\TransformerAbstract, instance of App\Transformers\UserTransformer given,
In a login controller when I print $user it print data
[original:protected] => Array
(
[id] => 2
[email] => test#test.com
[password] => $2y$10$fyORQUSfUpIhDjrIBD2TK.elGKwdzV10YOmLd9Goks3z52AUYi8mK
[status] => Active
[system_role] => User
[parent_user_id] => 0
[otp_verifiy_id] => 253526851
[last_login] => Carbon\Carbon Object
(
[date] => 2018-04-24 15:49:22.659941
[timezone_type] => 3
[timezone] => Asia/Calcutta
)
[remember_token] => eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTkyLjE2OC41LjE1ODo4MDAwL2FwaS9hdXRoL2xvZ2l
[created_at] => 2018-04-20 14:47:27
[updated_at] => 2018-04-24 15:49:22
)
After that I transform $user to UserTransformer
print_r($user);die; // above data
return $this->response->collection($user, new UserTransformer);
In my UserTransformer code look like
<?php
namespace App\Transformers;
use App\User;
use League\Fractal\TransformerAbstract;
use Illuminate\Http\Request;
class UserTransformer {
public function transform(User $user) {
print_r($user);die;
}
}
On a UserTransformer when i print $user it returns error.What am i doing wrong.?
Error is here:
return $this->response->collection($user, new UserTransformer);
The new UserTransformer is instance of App\Transformers\UserTransformer, but is should be instance ofLeague\Fractal\TransformerAbstract
Are you sure that class UserTransformer should not implement any Interface?
You need to extend TransformerAbstract in your UserTransformer class:
class UserTransformer extends TransformerAbstract {
public function transform(User $user) {
print_r($user);die;
}

Laravel : 3 tables linked with a central pivot. How to translate this to Laravel Eloquent ORM?

Hello and thanks for reading this,
A student have several courses and an individual project assigned to this course.
Multiple individual projects are available but only one by student by course.
If i want to know which individual project is assigned to student 10 for the course 1.. I could ask it this way.
Select Individual_project.* FROM Individual_project
INNER JOIN Students_has_Course ON Individual_project.id =
Students_has_Course.Individual_project_id
INNER Course ON Students_has_Course.Course_id = Course.id
INNER JOIN Students ON Students_has_Course.Students_id=Students.id
wHere Students.id=10 AND Course.id=1
I'm trying to translate these relations into Laravel models using Eloquent but I think that I'm missing something.
It's easy to make a relationship to find courses related to a students..
class Students extends Eloquent {
public function courses()
{
return $this->belongsToMany('Course','Students_has_Course','Course_id');
}
}
But I don't know how to make a complex join to obtain a collection of students with their courses and the related individual project for each of them.
Thanks again for reading this. I hope that it is understandable. English is not my first language and It's very late. I will provide more details if necessary.
You have a problem with your model. You shouldn't put courses and projects in the same pivot table. What happens when a single student, in a single course, has 3 projects and you query your pivot table? You get something like:
john doe =>
courses =>
course 1 =>
project 1 data
course 1 =>
project 2 data
course 1 =>
project 3 data
You would be better off breaking the different relationships into separate pivot tables. It is a bit more work, but it offers much more flexibility. Note that I changed the table/column names to match Laravel conventions.
class Course extends Eloquent {
protected $table = 'courses';
public function projects() {
return $this->belongsToMany('Project', 'course_project', 'course_id', 'project_id');
}
public function students() {
return $this->belongsToMany('Student', 'course_student', 'course_id', 'student_id');
}
}
class Student extends Eloquent {
protected $table = 'students';
public function courses() {
return $this->belongsToMany('Course', 'course_student', 'course_id', 'student_id');
}
public function projects() {
return $this->belongsToMany('Project', 'project_student', 'project_id', 'student_id');
}
}
class Project extends Eloquent {
protected $table = 'projects';
public function courses() {
return $this->belongsToMany('Course', 'course_student', 'course_id', 'student_id');
}
public function students() {
return $this->belongsToMany('Student', 'course_student', 'course_id', 'student_id');
}
}
$studentsCoursesProjects = Student::with('courses', 'courses.projects')->get()->toArray();
Array
(
[0] => Array
(
[id] => 1
[name] => John Doe
[courses] => Array
(
[0] => Array
(
[id] => 1
[name] => Intro to Laravel
[pivot] => Array
(
[course_id] => 1
[student_id] => 1
)
[projects] => Array
(
[0] => Array
(
[id] => 1
[desc] => Routing
[pivot] => Array
(
[course_id] => 1
[project_id] => 1
)
)
[1] => Array
(
[id] => 2
[desc] => Eloquent
[pivot] => Array
(
[course_id] => 1
[project_id] => 2
)
)
)
)
)
)
)
$studentsProjectsCourses = Student::with('projects', 'projects.courses')->get()->toArray();
Array
(
[0] => Array
(
[id] => 1
[name] => John Doe
[projects] => Array
(
[0] => Array
(
[id] => 1
[desc] => Routing
[pivot] => Array
(
[project_id] => 1
[student_id] => 1
)
[courses] => Array
(
[0] => Array
(
[id] => 1
[name] => Intro to Laravel
[pivot] => Array
(
[course_id] => 1
[student_id] => 1
)
)
)
)
)
)
)
Doing it this way gives you the ability to do all sorts of cool stuff with Eloquent.
$studentsCoursesProjectsFilter = Student::with(array('courses' => function($query) { }, 'courses.projects' => function ($query ) {
$query->where('projects.id', 1);
}))->get()->toArray();
EDIT:
If changing the db model isn't an option then you can do something like this:
class Student extends Eloquent {
protected $table = 'students';
public function courses() {
return $this->belongsToMany('Course', 'course_student', 'course_id', 'student_id');
}
public function projects() {
return $this->belongsToMany('Project', 'course_student', 'project_id', 'course_id');
}
}
$students = Student::with('courses', 'courses.projects')->get()->toArray();

Resources