How to show Nearby Places with Laravel API - php

I'm creating REST API with Laravel 5.6 (I have to say I'm new because I might have used the wrong terms. I'm sorry about that,I'm improving myself. I need to hear my faults :) )
I have one function for find nearby places in my controller
public function index(\Illuminate\Http\Request $request) {
if($request->has('party_category')){
$parties = Parties::where('party_category', $request->party_category)->get();//your new query here
}
else if($request->has('lat') && $request->has('long')){
$parties = Parties::whereRaw("ACOS(SIN(RADIANS('latitude'))*SIN(RADIANS($request->lat))+COS(RADIANS('latitude'))*COS(RADIANS($request->lat))*COS(RADIANS('longitude')-RADIANS($request->long)))*6380 < 10");
}else {
$parties = Parties::all();
}
return Fractal::includes('places')->collection($parties,new PartyTransformer);
}
and I'm using this url for send current location but when I giving them , laravel showing to me all parties not nearby.I want to show nearby places
http://127.0.0.1:8000/api/parties?lat=37.043237&long=27.392445
but when I sending my parameter to url it showing
{"data":[]}
I can't show any nearby places
also in my database I'm keeping lat and long like this :
public function up()
{
Schema::create('parties', function (Blueprint $table) {
$table->increments('id');
$table->integer('places_id')->unsigned();
$table->string('slug');
$table->string('party_title');
$table->string('party_category');
$table->string('rating')->nullable();
$table->date('party_date');
$table->string("latitude")->nullable();
$table->string("longitude")->nullable();
$table->integer('fav_count')->nullable();
$table->longText('image_path');
$table->longText('party_desp');
$table->timestamps();
});
}
How can I show the nearby ones ?

I fixed , I hope it will help somebody
class PartiesController extends Controller
{
public function index(\Illuminate\Http\Request $request) {
if($request->has('lat') && $request->has('long')){
$lat = $request->lat;
$long = $request->long;
$parties=DB::select(DB::raw("SELECT *,111.045*DEGREES(ACOS(COS(RADIANS(':lat'))*COS(RADIANS(`latitude`))*COS(RADIANS(`longitude`) - RADIANS(':long'))+SIN(RADIANS(':lat'))*SIN(RADIANS(`latitude`)))) AS distance_in_km FROM parties ORDER BY distance_in_km asc LIMIT 0,5"), array(
'lat' => $lat,
'long' => $long
));
$hidacik = Parties::hydrate($parties);
return Fractal::includes('places')->collection($hidacik,new PartyTransformer);
}
else {
$parties = Parties::all();
}
return Fractal::includes('places')->collection($parties,new PartyTransformer);
}
}

In $parties = Parties::whereRaw("ACOS(SIN(RADIANS('latitude'))*SIN(RADIANS($request->lat))+COS(RADIANS('latitude'))*COS(RADIANS($request->lat))*COS(RADIANS('longitude')-RADIANS($request->long)))*6380 < 10");
you are missing ->get(). you need to add get() in order to return a collection which you can then work with
//this returns a collection now since we added get()
$parties = Parties::whereRaw("ACOS(SIN(RADIANS('latitude'))*SIN(RADIANS($request->lat))+COS(RADIANS('latitude'))*COS(RADIANS($request->lat))*COS(RADIANS('longitude')-RADIANS($request->long)))*6380 < 10")->get();

Related

Eloquent get user with highest relation table points

I'm trying to get the user with the highest evaluation points based on charisma and persuasion
What i have wrote so far after this i couldn't figure out how to make it work
$user = User::where('commision_id', $data['commision'])->whereHas('role', function ($q) {
$q->where('level', 2);
})->with(['evaluations' => function ($q) {
}]);
The evaluations relation migration
Schema::create('evaluations', function (Blueprint $table) {
$table->id();
$table->boolean('charisma')->default(false);
$table->boolean('persuasion')->default(false);
$table->boolean('politics')->default(false);
$table->boolean('heat')->default(false);
$table->string('title');
$table->integer('hl')->nullable();
$table->integer('exp')->nullable();
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->index('user_id');
});
So basically i have to sum the exp points based on persuasion and the exp points based on charisma then sum both of those sum values to get the highest ranking user.
You can add up those 2 properties on the fly and simply get the one with the highest attribute.
$user = User::where('commision_id', $data['commision'])->whereHas('role', function ($q) {
$q->where('level', 2);
})->with(['evaluations'])
->get()
->each(function ($u) {
$u->score = $u->evaluations->charisma + $u->evaluations->persuasion
});
$topUser = $user->orderBy('score')->first();
In case one user can have many evaluations, you would do the similar thing:
->each(function ($u) {
$u->score = null;
$charisma = $u->evaluations->pluck('charisma')->sum();
$persuasion = = $u->evaluations->pluck('persuasion')->sum();
$u->score += $charisma;
$u->score += $persuasion ;
});
What made it work is using filter function to filter the boolean values of Charisma and Persuasion, thanks to N L which pointed me to the right direction, i accepted his answer.
$user = User::where('commision_id', $data['commision'])->whereHas('role', function ($q) {
$q->where('level', 2);
})->with(['evaluations'])
->get()
->each(function ($u) {
$u->score = null;
$charisma = $u->evaluations->filter(function($value) {
return $value->charisma == true;
})->sum('exp');
$persuasion = $u->evaluations->filter(function($value) {
return $value->persuasion == true;
})->sum('exp');
$u->score += $charisma;
$u->score += $persuasion;
})->sortByDesc('score')->first();

Generate automatically invoice with Laravel

I am working on a very simple project for my school assignment. So it's a house rent site. Everything seems fine but I want create an automatically invoice like "INV0001" but I don't know how to do that. Maybe you guys can help me fix my controller
This is my controller
public function storeSewa(Request $request){
if ($request->edit=='false') {
$newdata = new Sewa;
} else {
$newdata = Sewa::find($request->id);
if ($newdata) {
//
}else {
$newdata = new Sewa;}}
$newdata->invoice = 'INV/'//idk, how?
$newdata->penyewa_id = $request->penyewa_id;
$newdata->kamar_id = $request->kamar_id;
$newdata->tanggal_masuk = $request->tanggal_masuk;
$newdata->tanggal_keluar = $request->tanggal_keluar;
$newdata->durasi = $request->durasi;
$newdata->status = 'Belum Lunas';
$newdata->save();
if ($newdata) {
session()->flash('status', 'Task was successful!');
session()->flash('type', 'success');
return Redirect::route('account');
}
return 'false';
}
Well, I am very new to laravel, so is there anyone can help fix my problem in the easiest way?
if you are using database you can use sql auto increment, for this feature you have to have this line in your invoice models migration :
Schema::create('invoices', function (Blueprint $table) {
$table->Increments('id');
});
if you want your invoice numbers, not being like 1,2,3, ... you can use libraries like this:
https://github.com/oanhnn/laravel-fakeid
if you are using for test, you can use faker factory:
there is a tutorial here:
https://www.codermen.com/blog/75/how-to-use-faker-with-laravel-5-7-tutorial

Convert MYSQL query to Laravel way

I have to convert these queries to Laravel way.
$tqry = "select app_process,end_time,((end_time-".time().")/86400)as remain_day from BYAPPS_apps_data where mem_id='$valu[mem_id]' limit 1";
$tresult = $_DB->query($tqry);
$tmp=$tresult->fetchRow();
if($tmp[app_process]){
$status=$app_process[$tmp[app_process]];
if($tmp[app_process]==7&&($tmp[end_time]&&$tmp[remain_day]<=0)) $type="Expired";
}else {
$tqry = "select app_process from BYAPPS_apps_order_data where mem_id='$valu[mem_id]' order by idx desc limit 1";
$tresult = $_DB->query($tqry);
$tmp=$tresult->fetchRow();
if($tmp[app_process]) $status=$ord_process[$tmp[app_process]];
else $status="Not Customer";
}
I set the relation through the models like this.
UserInfo model
public function order()
{
return $this->hasMany('App\AppsOrderData', 'mem_id');
}
public function apps()
{
return $this->hasMany('App\AppsData', 'mem_id');
}
AppsOrderData model (=> Using 'BYAPPS_apps_order_data' table)
public function userinfo()
{
return $this->belongsTo('App\UserInfo', 'mem_id');
}
AppsData model (=> Using 'BYAPPS_apps_data' table)
public function payments()
{
return $this->hasMany('App\AppsPaymentData','mem_id');
}
Then, I tried to convert the original query in UserInfoController.php like below.
public function getUserInfoListData()
{
$userInfoListData = UserInfo::select('idx',
'mem_id',
'mem_nick',
'mem_name',
'cellno',
'ip',
'reg_date')
->with('order')
->with('apps');
$orderProcess = array('Cancel','Order', 'Confirm Order',
'Developing', 'App Uploaded', 'Service end',
'Service expired', '', '', 'Waiting');
$appsOrderData = AppsOrderData::select('app_process', 'mem_id', 'end_time');
return Datatables::of($userInfoListData)
->setRowId(function($userInfoListData) {
return $userInfoListData->idx;
})
->editColumn('type', function($eloquent) use ($appsOrderData, $orderProcess) {
if ($appsOrderData->app_process == 7 && $appsOrderData->end_time <= 0) {
return "Expired";
} else {
return "No Customer";
}
})
->editColumn('term', function($eloquent) {
return " (".$eloquent->launch_date." ~ ".now().")";
})
->orderColumn('reg_date', 'reg_date $1')
->make(true);
}
However, it doesn't return as I expected, all type data return just 'No Customer'.
How can I convert this query as laravel way?
Did I wrong make the relation?
I think there are some mistakes that you have done in your code,
AppData model doesn't have a user Relationship.
If you get() method to get data , You can do it in this way,
$userInfoListData= UserInfo ::
select('idx','mem_id','mem_nick','mem_name','cellno','ip','reg_date')
->with('order')
->with('apps')
->get();
For further reference you can use this:
Get Specific Columns Using “With()” Function in Laravel Eloquent
I hope this will help you to solve your issue- thanks!

query string with laravel

i have a problem with a query string in Laravel 5.6
I have this two entities, ER Schema:
and related model:
Note model
Location model
My problem is that I have to select all notes in a certain location passing as query string parameters latitude and longitude.
A query string could be:
homestead.test/api/notes?lat=45.5432&long=43.6543&max_distance=1.1
I try to build a query Here the NoteController code, but there is a problem:
Actually the output show me every note.
This is a postman output and in addition to the notes in the right location, I also return those with location = null. Going to see in the database these notes have only one parameter that coincides with those passed in query string. Theoretically it should not return them and I can not take them off in any way. could someone help me?
I hope I was clear enough, thanks in advance
Node::with(['location' => function($query) use ($latitude, $longitude){
$query->where('latitude', $latitude);
$query->where('longitude', $longitude);
}])->get()
If it can help someone, I solved the problem in this way.
public function index(Request $request) {
if($request->has('lat') &&
$request->has('long')) {
$lat1 = $request->query('lat');
$long1 = $request->query('long');
$max_distance = $request->query('max_distance');
$notes = Note::All();
foreach ($notes as $key => $value) {
if($value->location != null) {
$lat2 = $value->location->latitude;
$long2 = $value->location->longitude;
$distance = sqrt(pow($lat2-$lat1, 2) + pow($long2-$long1, 2));
if($distance > $max_distance) {
$notes->forget($key);
}
} else {
$notes->forget($key);
}
}
return $notes;
}
return Note::All();

Laravel detect if there is a new item in an array

I want to implement a system in my project that "alerts" users when there is a new comment on one of their posts.
I currently query all comments on the posts from the logged in user and put everything in an array and send it to my view.
Now my goal is to make an alert icon or something when there is a new item in this array. It doesn't have to be live with ajax just on page load is already good :)
So I've made a function in my UsersController where I get the comments here's my code
public function getProfileNotifications()
{
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
//comments
if (!empty($projects)) {
foreach ($projects as $project) {
$comments_collection[] = $project->comments;
}
}
if (!empty($comments_collection)) {
$comments = array_collapse($comments_collection);
foreach($comments as $com)
{
if ($com->from_user != Auth::user()->id) {
$ofdate = $com->created_at;
$commentdate = date("d M", strtotime($ofdate));
$comarr[] = array(
'date' => $ofdate,
$commentdate,User::find($com->from_user)->name,
User::find($com->from_user)->email,
Project::find($com->on_projects)->title,
$com->on_projects,
$com->body,
Project::find($com->on_projects)->file_name,
User::find($com->from_user)->file_name
);
}
}
} else {
$comarr = "";
}
}
Is there a way I can check on page load if there are new items in the array? Like keep a count and then do a new count and subtract the previous count from the new one?
Is this even a good way to apprach this?
Many thanks in advance! Any help is appreciated.
EDIT
so I added a field unread to my table and I try to count the number of unreads in my comments array like this:
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
//comments
if (!empty($projects)) {
foreach ($projects as $project) {
$comments_collection[] = $project->comments;
}
}
$unreads = $comments_collection->where('unread', 1);
dd($unreads->count());
But i get this error:
Call to a member function where() on array
Anyone any idea how I can fix this?
The "standard" way of doing this is to track whether the comment owner has "read" the comment. You can do that fairly easily by adding a "unread" (or something equivalent) flag.
When you build your models, you should define all their relationships so that stuff like this becomes relatively easy.
If you do not have relationships, you need to define something like the following:
In User
public function projects()
{
return $this->hasMany('App\Models\Project');
}
In Project
public function comments()
{
return $this->hasMany('App\Models\Comment');
}
Once you hav ethose relationshipt, you can do the following. Add filtering as you see fit.
$count = $user->projects()
->comments()
->where('unread', true)
->count();
This is then the number you display to the user. When they perform an action you think means they've acknowledged the comment, you dispatch an asynchronous request to mark the comment as read. A REST-ish way to do this might look something like the following:
Javascript, using JQuery:
jQuery.ajax( '/users/{userId}/projects/{projectId}/comments/{commentId}', {
method: 'patch'
dataType: 'json',
data: {
'unread': false
}
})
PHP, in patch method:
$comment = Comment::find($commentId);
$comment->update($patchData);
Keep in mind you can use Laravel's RESTful Resource Controllers to provide this behavior.
try this
$unreads = $project->comments()->where('unread', 1);
dd($unreads->count());
EDIT
My be Has Many Through relation will fit your needs
User.php
public function comments()
{
return $this->hasManyTrough('App\Project', 'App\Comment');
}
Project.php
public function comments()
{
return $this->hasMany('App\Comment');
}
then you can access comments from user directly
$user->comments()->where('unread', 1)->count();
or I recommend you define hasUnreadComments method in User
public function hasUnreadComments()
{
$return (bool) $this->comments()->where('unread', 1)->count();
}
P.S.
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
this code is horrible, this way much better
$projects = Auth::user()->projects;

Categories