use a custom function inside a laravel select - laravel

I have a query that needs to use a custom function like is showed below.
The problem is that one of the parameters is a value of another field from the same query.
The function is "calcula_distancia" and "$ofps[0]->latitude" and "$ofps[0]->longitude" are fields from a previus query.
The function needs 4 parameters and the last two are field from $necps that is beeing selected, but I can not retrieve the value from it using just 'participantes.latitude' or even without cotes. It passes a string only, to the function.
So, how can I pass the value from this fields beeing selected to the function?
Tryed to use RAW but not work.
Sorry for the big question. thanks! :-)
use App\Classes\MinhasFuncoes;
$mf = new MinhasFuncoes();
$necps = DB::table('necessidades_part')->where('necessidades_part.id_part',"<>",$id_part)
->where(function($query) use ($searchValues){
foreach ($searchValues as $value) {
if(strlen($value)>3){
$query->orwhere('obs','like','%'.($value).'%')
->orwhere('necessidades.descricao','like','%'.($value).'%')
->orwhere('categorias.descricao','like','%'.($value).'%');
}
}
})
->join('participantes','necessidades_part.id_part','=','participantes.id')
->join('necessidades','necessidades_part.id_nec','=','necessidades.id')
->join('categorias','necessidades.id_cat','=','categorias.id')
->join('unidades','necessidades.id_unid','=','unidades.id')
->select('participantes.id as id_part','participantes.nome_part','participantes.latitude',
'participantes.longitude','participantes.nome_part','necessidades_part.id as id_nec_part',
'necessidades_part.id_nec','necessidades_part.quant','necessidades_part.data',
'necessidades_part.obs','necessidades.descricao as desc_nec',
'categorias.descricao as desc_cat','unidades.descricao as desc_unid',
$mf->calcula_distancia($ofps[0]->latitude,$ofps[0]->longitude,'participantes.latitude',
'participantes.longitude').' as distancia')
->orderBy('data','desc')
->paginate(10);

you can not execute your PHP function inside of your DB query. you should use MySQL function instead of that or you should fetch results from the database then map your result just in PHP

Related

How to apply an operation/functionality on one column during getting data of a table in Laravel Controller?

I want to get all the data of today's Date, but during getting it I want to apply an operation on the data of one column only NOT others. This operation is from another function.
$data = Net::whereDate('created_at', Carbon::today())->get();
I have two options:
During getting data, call to that function on the specific column
After getting data, put a loop and then apply that operation and save data into new object
In this table, there is a column called profit, and I want to encode this profit into alphabets by calling encode_code() function remaining the other data as it is.
I don't know how I can do this, please help me if anyone knows.
You can use a foreach loop to get each object from the collection and for each of those object,call the desired function.
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $key => $dat)
{
$data[$key]->profit = encode_code($dat->profit);
}
I think you should call the function and turn it like this
I just didn't know what you wanted to do, so this is my best
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $i => $d){
$data[$i]->profit = encode_codeļ¼ˆ$d->profit);
}
Of course you could loop through your result and encode each row, but this would prevent you from reusing this code.
Instead you could put that encode function directly into the model, so that you can reuse it everywhere:
public function getEncodedProfit() {
return encode_code($this->profit);
}
Now you can just use this function everywhere in your controllers or views like that:
echo $net->getEncodedProfit();

Manual function inside query?

Is there any way to put a manual function inside a query in Laravel.
I've timestamp saved in string in DB. I want to convert timestamp from one timezone to another. All the timestamp is inserted in one time zone, and depending upon my user I fetch the timestamp and convert it into their timezone.
what I want to achieve is something like this..
$query = BlogCategory::select('merchant_id', userTime(added_at))
->where('site_id', $site_id)
->get();
userTime() function takes two parameter, the timestamp and the timezone and converts the timsestamp to time of the user.
I want to use userTime() function before fetching the data. I dont want to fetch the data first and then do foreach and so on.
I know I might be absolutely absurd but is there anything of this sort in Laravel?
Well you can achieved that using collection map
$query = BlogCategory::select('merchant_id', 'added_at')
->where('site_id', $site_id)
->get();
$dateAdded = $query->map(function ($data) {
// try this if error $data['merchant_id']
return array(
'merchant_id' => $data->merchant_id,
'added_at' => $this->userTime($data->added_at)
);
})
dd($dateAdded);
Read Collection documentation here: https://laravel.com/docs/5.8/collections
You should use the selectRaw statement and let your DB do this logic for you if you don't want to loop over the result set.
For example if your underlying database is MySQL you can use the CONVERT_TIMEZONE function and do something like this.
BlogCategory::selectRaw('merchant_id, CONVERT_TZ(added_at, "GMT", "MET") as added_at')
->where('site_id', $site_id)
->get();

changing a query result value according to wherehas condition in laravel

I am using laravel
I want to change the value of a column according to a specific condition.
if a condition is satisfied in wherehas then change the value of specific column to 1 let's say.How could i do it.
if i can call a function in the model inside the wherehas function to change the value how could I do it ??
i can iterate the result set using a 2 for loops and change it, however I want to decrease the complexity by changing the value while retrieving the data
Course::with('stages','stages.levels')->whereHas('stages.levels', function($query)use ($levelsarray){
$query->wherenotIn('id', $levelsarray);
here I want to change a column value in table levels
})->first();
Here is a general way,
Assuming you have Three models, Course, Stage, Level
When you are retrieving data from Level model, add an accessor,
For more info click here.
Eg:
On Level.php model,
public function getColumnNameAttribute($value) // replace ColumnName with column name
{
//write application logic here.
return $value;
}

How to select specific columns in laravel eloquent

lets say I have 7 columns in table, and I want to select only two of them, something like this
SELECT `name`,`surname` FROM `table` WHERE `id` = '1';
In laravel eloquent model it may looks like this
Table::where('id', 1)->get();
but I guess this expression will select ALL columns where id equals 1, and I want only two columns(name, surname). how to select only two columns?
You can do it like this:
Table::select('name','surname')->where('id', 1)->get();
Table::where('id', 1)->get(['name','surname']);
You can also use find() like this:
ModelName::find($id, ['name', 'surname']);
The $id variable can be an array in case you need to retrieve multiple instances of the model.
By using all() method we can select particular columns from table like as shown below.
ModelName::all('column1', 'column2', 'column3');
Note: Laravel 5.4
You first need to create a Model, that represent that Table and then use the below Eloquent way to fetch the data of only 2 fields.
Model::where('id', 1)
->pluck('name', 'surname')
->all();
Also Model::all(['id'])->toArray() it will only fetch id as array.
Get value of one column:
Table_Name::find($id)->column_name;
you can use this method with where clause:
Table_Name::where('id',$id)->first()->column_name;
or use this method for bypass PhpStorm "Method where not found in App\Models":
Table_Name::query()->where('id','=',$id)->first()->column_name;
in query builder:
DB::table('table_names')->find($id)->column_name;
with where cluase:
DB::table('table_names')->where('id',$id)->first()->column_name;
or
DB::table('table_names')->where('id',$id)->first('column_name');
last method result is array
You can use get() as well as all()
ModelName::where('a', 1)->get(['column1','column2']);
From laravel 5.3 only using get() method you can get specific columns of your table:
YouModelName::get(['id', 'name']);
Or from laravel 5.4 you can also use all() method for getting the fields of your choice:
YourModelName::all('id', 'name');
with both of above method get() or all() you can also use where() but syntax is different for both:
Model::all()
YourModelName::all('id', 'name')->where('id',1);
Model::get()
YourModelName::where('id',1)->get(['id', 'name']);
To get the result of specific column from table,we have to specify the column name.
Use following code : -
$result = DB::Table('table_name')->select('column1','column2')->where('id',1)->get();
for example -
$result = DB::Table('Student')->select('subject','class')->where('id',1)->get();
use App\Table;
// ...
Table::where('id',1)->get('name','surname');
if no where
Table::all('name','surname');
If you want to get a single value from Database
Model::where('id', 1)->value('name');
Also you can use pluck.
Model::where('id',1)->pluck('column1', 'column2');
You can use Table::select ('name', 'surname')->where ('id', 1)->get ().
Keep in mind that when selecting for only certain fields, you will have to make another query if you end up accessing those other fields later in the request (that may be obvious, just wanted to include that caveat). Including the id field is usually a good idea so laravel knows how to write back any updates you do to the model instance.
You can get it like
`PostModel::where('post_status', 'publish')->get(['title', 'content', 'slug', 'image_url']`)
link
you can also used findOrFail() method here it's good to used
if the exception is not caught, a 404 HTTP response is automatically sent back to the user. It is not necessary to write explicit checks to return 404 responses when using these method not give a 500 error..
ModelName::findOrFail($id, ['firstName', 'lastName']);
While most common approach is to use Model::select,
it can cause rendering out all attributes defined with accessor methods within model classes. So if you define attribute in your model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the user's first name.
*
* #param string $value
* #return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
And then use:
TableName::select('username')->where('id', 1)->get();
It will output collection with both first_name and username, rather than only username.
Better use pluck(), solo or optionally in combination with select - if you want specific columns.
TableName::select('username')->where('id', 1)->pluck('username');
or
TableName::where('id', 1)->pluck('username'); //that would return collection consisting of only username values
Also, optionally, use ->toArray() to convert collection object into array.
If you want to get single row and from the that row single column, one line code to get the value of the specific column is to use find() method alongside specifying of the column that you want to retrieve it.
Here is sample code:
ModelName::find($id_of_the_record, ['column_name'])->toArray()['column_name'];
If you need to get one column calling pluck directly on a model is the most performant way to retrieve a single column from all models in Laravel.
Calling get or all before pluck will read all models into memory before plucking the value.
Users::pluck('email');
->get() much like ->all() (and ->first() etc..) can take the fields you want to bring back as parameters;
->get/all(['column1','column2'])
Would bring back the collection but only with column1 and column2
You can use the below query:
Table('table')->select('name','surname')->where('id',1)->get();
If you wanted to get the value of a single column like 'name', you could also use the following:
Table::where('id', 1)->first(['name'])->name;
For getting multiple columns (returns collection) :
Model::select('name','surname')->where('id', 1)->get();
If you want to get columns as array use the below code:
Model::select('name','surname')->where('id', 1)->get()->toArray();
If you want to get a single column try this:
Model::where('id', 1)->first(['column_name'])->column_name;

Join query in laravel with data manipulation send to view

I am having 2 tables, users and profiledetails
I am able to run Join query and access the data and send to view.
But when I am manipulation the field 'dob' (date format) in profiledetails table. No Success, Please check the code below ,
webpagesConroller:
$users = DB::table('users')
->join('profiledetails', 'users.id', '=', 'profiledetails.user_id')
->select('users.*', 'profiledetails.dob')
->get();
$age = $users->dob->diffInYears(Carbon::now());
return view('webpages.index',compact('users'))->with($age);
View:
<li class="cate_head">Age : {{ $age}}</li>
Error:
Trying to get property of non-object
I have model Profiledetails added the mutators as below,
public function getAge(){
return $this->dob->diffInYears(Carbon::now());
}
public function getDOB(){
return $this->dob->format('d-m-Y');
}
Can I not use this method on another controller for Ex- webpagesController, If yes How.
Since you are using a raw query, the data returned is not an object but an array with the data.
Also you did not limit the query, meaning it could return multiple rows.
You'll probably need to get the data from the $users as:
//with the possibily of multiple rows. Index is the row which has to be used
$users[index]['dob']
//when you are sure it only returns one row
$users[0]['dob'] // or $users['dob'] not sure as of the moment
You want to check the differences with Carbon.
So you will probably need to make a Carbon object of the dob result and check it against the Carbon::now.
$age = Carbon::createFromFormat('Y-m-d', $users[0]['dob'])->diffForHumans();
// diffForHumans() uses the local time
Note that this only gets the age for one row (the index or the first because of [0]).
If you want to do it for every row use a for or foreach where you set the $users->age for every $user. But as these are not object/models but raw data, this will not work.
Hope this helps your question a bit

Resources