Use variable on the mysql like sentence on laravel query builder - mysql

$key was a variable can be empty or something.
var key='"<?php echo $_REQUEST['key']; ?>"';
then send to the ajax by data
"ajax": {
"url": "{{asset("try")}}",
"type": 'POST',
"dataType": 'json',
"async": true,
"data": {
key : key,
},
}
the try Controller
public function try(Request $request){
$key=$request->key;
DB::query()
->select('A.id','A.upper_p_id','A.key')
->from('users as A')
->leftjoin('products as B', function($join) {
$join->on('A.ID', '=', 'B.p_id');
})
->groupBy('A.id','A.upper_p_id','A.key')
->where('A.key', 'LIKE', '%'.$key.'%');
->get()
return $result;
}
I got the error expression from the queries debug tool?
LIKE '%\"\"%'
But if I use
->where('A.n_geography','LIKE', '%'.''.'%');
It is right sentence from the queries debug tool.
LIKE '%%'

Well - you did put in the double quotes in the key variable...
So it's doing it correctly :-)

If you are trying to get key from request, you ideally should no use $_GET o $_POST.
public function getData(Request $request){
$key = $request->key;
$records = DB::table('users')
->leftJoin('products', 'users.id', '=', 'products.p_id')
->groupBy('users.id','users.upper_p_id','users.key')
->where('users.key', 'LIKE', '%'.$key.'%')
->select('users.id','users.upper_p_id','users.key')
->get();
return response()->json($records, 200);
}
However if the key variable is a javascript variable, then you can not directly use in controller. You need to pass it somehow in route param or using ajax request.
Secondly if you can add conditional when that if $key is present then only do a where clause :
public function getData(Request $request){
$key = $request->key;
$records = DB::table('users')
->leftJoin('products', 'users.id', '=', 'products.p_id')
->groupBy('users.id','users.upper_p_id','users.key')
->when($key, function($q) use($key){
return $q->where('users.key', 'LIKE', '%'.$key.'%');
})
->select('users.id','users.upper_p_id','users.key')
->get();
return response()->json($records, 200);
}

You're double quoting key. The suggested way to share PHP variables as JS variables is to JSON encode them for example:
var key= {!! json_encode(request()->input('key')) !!};
Note that there are no additional quotes necessary in the JS code because valid JSON is also a valid JS variable.
Also note that since you are using Laravel it is recommended you use blade markup and the request() helper for accessing the request parameters

In order to prevent SQL injection it is better not to concatenate the value directly but pass it as a param so try this:
$key = $request->key;
...
->whereRaw('A.key like ?', ['%' . $key . '%']);
And in your JS:
var key='<?php echo $_REQUEST['key']; ?>';

Related

Is it possible to add some string before Column value in Laravel?

So, i need to put AWS S3 URL before the attachment value. I use Laravel Query builder to get data from database.
Query
$query = DB::table('subscriber')->select(['ID as SBC_ID','SUBSCRIBER_NAME','ATTACHMENT_OTHERS'])
->get();
return $query;
Result
[
{
"SBC_ID": 1,
"SUBSCRIBER_NAME": "NAME",
"ATTACHMENT_OTHERS": "uploads/1655362922-Annotation%202022-05-31%20141139.png"
},
{
"SBC_ID": 2,
"SUBSCRIBER_NAME": "NAME 2",
"ATTACHMENT_OTHERS": "uploads/1655362922-image.png"
}
]
The ATTACHMENT_OTHERS is from Form Request and uploaded to AWS S3. I just insert the attachment path, not full S3 URL. But now, i need to return full URL.
Let say i put my AWS url in the .env file.
AWS_URL=https://loremipsum.s3.ap-southeast-1.amazonaws.com
Is it possible to return the result from my query builder ?
You can use Laravel Raw Expressions and MySQL CONCAT function. E.g.:
$query = DB::table('subscriber')
->select([
'ID as SBC_ID',
'SUBSCRIBER_NAME',
DB::raw('CONCAT(\'https://loremipsum.s3.ap-southeast-1.amazonaws.com\', ATTACHMENT_OTHERS) as ATTACHMENT_OTHERS')
])->get();
Additionally, you put that url in .env
AWS_URL=https://loremipsum.s3.ap-southeast-1.amazonaws.com
and create new config file, e.g. config/aws.php
return [
'attachment_url' => env('AWS_URL', 'AWS_URL'),
]
and then you can have a little neater code:
$query = DB::table('subscriber')
->select([
'ID as SBC_ID',
'SUBSCRIBER_NAME',
DB::raw('CONCAT(\''.config('aws.attachment_url').'\', ATTACHMENT_OTHERS) as ATTACHMENT_OTHERS')
])->get();
If you returning this data via JSON API, then I suggest that you use Laravel API Resources
You can use SQL's built-in function CONCAT() with DB facade, something like like this:
use Illuminate\Support\Facades\DB;
// ...
$aws_host = "https://loremipsum.s3.ap-southeast-1.amazonaws.com" . "/";
$query = DB::table('subscriber')->select([
'ID as SBC_ID',
'SUBSCRIBER_NAME',
DB::raw('CONCAT("' . $aws_host . '", ATTACHMENT_OTHERS) AS ATTACHMENT_OTHERS'),
])->get();
$query = DB::table('subscriber')->select(['ID as SBC_ID','SUBSCRIBER_NAME','ATTACHMENT_OTHERS'])
->get();
$AWS_URL = "https://loremipsum.s3.ap-southeast-1.amazonaws.com/";
foreach($query as $result)
{
$SBC_ID = $result->SBC_ID;
$SUBSCRIBER_NAME = $result->SUBSCRIBER_NAME;
$ATTACHMENT_OTHERS = $AWS_URL.$result->ATTACHMENT_OTHERS;
}
$query = ([
'SBC_ID' => $SBC_ID,
'SUBSCRIBER_NAME' => $SUBSCRIBER_NAME,
'ATTACHMENT_OTHERS' => $ATTACHMENT_OTHERS
]);
return $query;

SQL Laravel Eloquent - Where field can be uppercase or lowercase

$pname can be "Airbus", "airbus" or "AIRBUS"
$info = Plane::where('plane_name', '=', $pname)
->where('uid', '=', $uid)
->get();
Is there any way I can update this query to check the database for the plane name without case sensitivity?
Use LOWER MYsql function and strtolower php function
$info = Plane::whereRaw('LOWER(plane_name) = (?)', [strtolower($pname)])
->where('uid', '=', $uid)
->get();
OR
Plane::where('plane_name', 'ilike', $pname)->where('uid', '=', $uid)
->get();
just make sure result where clause to lowercase and query clause to lowercase too.
where(DB::raw('lower(column_name)'), '=', Str::lower($query))
dont forget to use:
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
Add -> use Illuminate\Support\Facades\DB; in Controller file.
-----------Example---------------
UserInfo::where(DB::raw('upper(username)'), strtoupper($Request->username))
It's work for me, hope to help you.
To solve my issue, I have to do that on my Model.
simple copy and paste this function
public function __get($key)
{
if (is_null($this->getAttribute($key))) {
return $this->getAttribute(strtoupper($key));
} else {
return $this->getAttribute($key);
}
}

Laravel Eloquent model JSON output format

my problem is about the JSON format I recieve when sending a query to the database.
The output I want:
[{"errors":[{"something":"something"}],"created_at":"2020-10-20 10:10:10","name":"something","id":99}]
I get :
[{"id":99,"name":"something","device_results":[{"devices_id":99,"created_at":"2020-10-20 10:10:10","errors":[{"something":"something"}]}]}]
Which I get with:
public function errors()
{
$errors = DB::table('devices')
->join('device_results', 'devices.id', '=', 'device_results.devices_id')
->select('errors', 'created_at', 'name', 'device_results.id')
->orderBy('created_at', 'desc')
->whereJsonLength('errors', '>', 0)
->get();
return $errors;
}
I would like to get the same results with using my model because if I do this:
public function errors()
{
$devices = Devices::with(['device_results' => function($query) {
$query->select('device_results.devices_id','created_at','errors')
->whereJsonLength('errors', '>', 0)
->orderBy('created_at', 'desc')
->get();
}])->get();
return $devices;
}
Is it always in this format or can I use the model and get the same format as with the DB class? I am using Vue for the front end and would like to avoid nesting.
Thank you
Have you tried to create a Resource ?
The doc : https://laravel.com/docs/8.x/eloquent-resources

Eloquent: Select field from whereHas block fails

I have got a slightly complex SQL query using a combination of where, whereHas, orWhereHas etc.
Everything goes well but when I add 'custom_records.custom_title' (see below) into the Select fields it fails with:
The Response content must be a string or object implementing __toString(), "boolean" given.
Any ideas?
Here it's the snippet:
`
$record = $this->record->newQuery();`
$record->whereHas('customRecords', function ($query) use ($searchTerm) {
$query->where('custom_title', 'like', '%'.$searchTerm.'%');
});
return $record->get([
'records.id',
'records.another_field',
'records.another_field_2',
'custom_records.custom_title',
]);
Update
When I run the produced SQL query on a mysql client it comes back with:
Unknown column 'custom_records.custom_title',' in 'field list'
You can't select custom_records.custom_title like that. Since it's a HasMany relationship, there can be multiple custom_records per record.
You have to do something like this:
$callback = function ($query) use ($searchTerm) {
$query->where('custom_title', 'like', '%'.$searchTerm.'%');
};
Record::whereHas('customRecords', $callback)
->with(['customRecords' => $callback])
->get(['id', 'another_field', 'another_field_2']);

Where clause with a blank variable Laravel

I use GET, to collect a variable :
$subid = $_GET['subid'];
In my DB Query i have the following :
->where('subID', '=', $subid)
Now if the variable $subid is blank , the result returns no information. How do i specify in the query that if the variable $subid is blank or empty, return all results?
You can use when.
->when($subid, function ($query) use ($subid) {
return $query->where('subID', '=', $subid);
})
If $subid is false the where condition won't be applied to the query.
Check out the doc https://laravel.com/docs/5.2/queries#conditional-statements
UPDATE:
Any expression that you can be used inside an if call can be used as the first argument of when
An example :
->when($fromDate && $toDate, function($query) use ($fromDate, $toDate) {
return $query->whereBetween('CompletedDate', array($fromDate, $toDate));
})
You can use orWhere():
->where('subID', '=', $subid)
->orWhere('subID', '=', '');