i´m traying to get of my DB to lowercase column data with model::where
this is my query:
$restaurants = Restaurant::where('name', 'LIKE', "%".$search."%")->get();
$results = [];
foreach ($restaurants as $r) {
$data = array(
'id' => $r->id,
'label' => $r->name,
'value' => $r->name,
'url' => $r->url,
);
array_push($results, $data);
}
i´m traying with this:
$restaurants = Restaurant::whereRaw('LOWER(name) = ?', [$search])->get();
but return empty results.
How i would can to do this?. In my database it´s all in uppercase i need search in uppercase or lowercase
Thanks for help
If you are using MySQL, MariaDB or PostgreSQL you could simply use a special version of LIKE that does not care for case: ILIKE:
$restaurants = Restaurant::where('name', 'ILIKE', "%".$search."%")->get();
$results = [];
foreach ($restaurants as $r) {
$data = array(
'id' => $r->id,
'label' => $r->name,
'value' => $r->name,
'url' => $r->url,
);
array_push($results, $data);
}
To be more efficient still you could use a collation on that field (or table, or database) on the database that is case insensitive, so every comparison ever made will be case insensitive (Beware that if you have and primary or unique key with an case insensitive collation you cannot have mulple entries with the same text only varying casing).
try this
$restaurants = Restaurant::whereRaw('LOWER(`name`) LIKE ? ',[trim(strtolower($search)).'%']);
if it's not work just add ->get() at last query
Related
Solution
foreach($request->all() as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']], $record);
}
Question
How do I update a whole table by passing a request array? It should update existing rows and create new ones if id doesn't exist. If possible without having to loop over the whole table.
Attempts that don't work:
EventViews::query()->updateOrCreate($request->all());
.
DB::transaction(function ($request) {
foreach ($request->all() as $record) {
EventViews::updateOrCreate($record);
}
});
.
$model = new EventViews($request->all());
$model->fill($request->all())->save();
assuming your request payload looks something like
records[]=[id=1,name=foo,description=foo,c=1]&
records[]=[id=2,name=bar,description=bar,c=1]&
...
you could loop over it like:
$input = $request->input('records');
foreach($input as $record){
EventViews::query()->updateOrCreate(['id'=>$record['id']],$record);
}
if your request looks like:
1=[name=foo,description=foo,c=1]&
2=[name=bar,description=bar,c=1]&
...
where the parameter name is the id, then you could use:
$input = $request->input();
foreach($input as $key => $record){
EventViews::query()->updateOrCreate(['id'=>$key],$record);
}
updateOrCreate receives 2 parameters, the first is the constrains and the second is the data.
I don't know your request structure, but it's good practice verify it before throwing it into your database.
Example:
Model::query()->updateOrCreate(
['my_column' => $request->input('my_column')],
[*array of column/values of what should be updated*]
)]
If exists a Model with given my_column value, it will update it's value with the associative array passed on the second argument, otherwise it will create a new entry.
you can use this method :
$flight = Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
or
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
for get more information see this link:
https://laravel.com/docs/9.x/eloquent#upserts
Laravel provides a great help for developers to save all input fields of a form which is one record with one line of code.
like if I want to save a form which has multiple input fields and one record to database like:
then I can save it with below code and it works great:
SaveOrder:: create($request->all());
Now I have a question. If I have multiple records (multiple rows) in a form and I can add new rows with a button pressed. Then how can I save all records with above code?
Like:
It's easy to do that using Eloquent :
$data = array(
array('field1'=>'value1', 'field2'=> value2),
array('field1'=>'value1', 'field2'=> value1),
//...
);
Model::insert($data);
Assuming your input names look something like name[], since you can add rows on the fly, you can retrieve the input as an array, and insert them using something like this:
$data = [];
$names = request('name');
$product_names = request('product_name');
$product_colour = request('product_colour');
$product_size = request('product_size');
for ($i = 0; $i < count($names); $i++) {
// Add checks to make sure indices actually exist, probably using preprocessing in JS
$data[] = [
'name' => $names[$i],
'product_name' => $product_names[$i],
'product_colour' => $product_colour[$i],
'product_size' => $product_size[$i],
];
}
Model::insert($data);
The best answer for this question is using foreach statement. Like:
$CustomerName= $request -> input('CustomerName');
$ProductId= $request -> input('ProductId');
$ProductName= $request -> input('ProductName');
$ProductColor= $request -> input('ProductColor');
foreach( $ProductId as $key => $n ) {
SaveOrder::insert(
array(
'CustomerName' => $CustomerName[$key],
'ProductId' => $ProductId[$key],
'ProductName' => $ProductPrice[$key],
'ProductColor' => $ProductQuantity[$key],
)
);}
Use upsert
If you use Laravel 8 or above, you can make use of upsert. Such an useful function to insert or update matching records at the same time.
SaveOrder::upsert($request->all(), ['id'], ['CustomerName', 'ProductName', 'ProductColor', 'ProductID']);
The method's first argument consists of the values to insert or update, while the second argument lists the column(s) that uniquely identify records within the associated table. The method's third and final argument is an array of the columns that should be updated if a matching record already exists in the database. The upsert method will automatically set the created_at and updated_at timestamps if timestamps are enabled on the model:
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
Read the documentation on Laravel Upsert
I want to display all documents (select *) with sub-documents in PHP.
I know how to query all find() but I have no idea how to do it when I have sub-documents. I don't know if there's something like find() or I need to make loops fo every sub-documents that I'd have.
This would be the code
$mongodatabase->insertOne(
['name' => 'Alex',
'surname' => 'Turner',
'country' => 'England',
'birth' => array(
'day' => 6,
'month' => 'january',
'year' => 1986
),
]);
Something easy, just to learn. When I try a var_dump of day I get Undefined index and NULL.
$client = new MongoDB\client;
$db = $client->database;
$mongodatabase = $db->document;
$document = $mongodatabase->find();
foreach ($document as $doc) {
var_dump($doc->day);
}
However, I'd like to query all.
Use $exists - It helps us in identifying the elements which are not empty
db.collection_name.find({
"birth.day" : {
$exists : true
}
});
If you need to check not null and empty, then we need to use $type together with $exists, $type can be passed with different values and 10 is for null check
db.collection_name.find({
"birth.day" : {
$not : { $type : 10 },
$exists : true
}
});
when u find the exactly data from mongoldb u can use the shelter to limit the field
eg:
db.xxxxx.find(
{'status':'DELIVRD'}
);
I'm trying to receive some ids from my database for an autocomplete search on my CAKEPHP 3.3 site. But my problem is that its only returning the id if I type in the exact id and not part of it.
Here is my function to search the data. The name variable is what is being passed from input.
public function search()
{
if ($this->request->is('ajax'))
{
$name = $this->request->query['term'];
$resultArr = $this->Invoices->find('all', [
'conditions' => ['Invoices.id LIKE' => ($name . '%')]
]);
$resultsArr = [];
foreach ($resultArr as $result)
{
$resultsArr[] = ($result['id']);
}
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', ['resultsArr']);
}
}
For example there is a id in the table '5254' and I type in part of the id '52' nothing is returned but when I type in the whole id '5254' the id is returned.
I'm unsure why this is the case because in my sql query i'm using the percent sign to say any characters after what has been typed into the input.
Here is part of my table
SQL debug when 52 is entered.
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Invoices.id AS `Invoices__id`, Invoices.start_date AS `Invoices__start_date`, Invoices.close_date AS `Invoices__close_date`, Invoices.customer_id AS `Invoices__customer_id`, Invoices.invoice_to_address AS `Invoices__invoice_to_address`, Invoices.ship_to_address AS `Invoices__ship_to_address`, Invoices.customer_contact_id AS `Invoices__customer_contact_id`, Invoices.aircraft_registration_id AS `Invoices__aircraft_registration_id`, Invoices.shipping_company_id AS `Invoices__shipping_company_id`, Invoices.notes AS `Invoices__notes`, Invoices.worksheet_notes AS `Invoices__worksheet_notes`, Invoices.closed AS `Invoices__closed`, Invoices.times_printed AS `Invoices__times_printed`, Invoices.payment_due AS `Invoices__payment_due`, Invoices.GST_rate AS `Invoices__GST_rate`, Invoices.opening_notes AS `Invoices__opening_notes`, Invoices.courier_ticket AS `Invoices__courier_ticket`, Invoices.job_description AS `Invoices__job_description`, Invoices.worksheets_printed AS `Invoices__worksheets_printed`, Invoices.supervising_engineer_id AS `Invoices__supervising_engineer_id`, Invoices.job_type_id AS `Invoices__job_type_id`, Invoices.opened_by_id AS `Invoices__opened_by_id`, Invoices.assigned_to_id AS `Invoices__assigned_to_id`, Invoices.certification_required AS `Invoices__certification_required`, Invoices.currency_id AS `Invoices__currency_id`, Invoices.xero_batch_number AS `Invoices__xero_batch_number`, Invoices.xero_amount AS `Invoices__xero_amount`, Invoices.exchange_rate AS `Invoices__exchange_rate`, Invoices.payment_instructions AS `Invoices__payment_instructions`, Invoices.email AS `Invoices__email`, Invoices.inv_email AS `Invoices__inv_email` FROM invoices Invoices WHERE Invoices.id like :c0',
'params' => [
':c0' => [
'value' => '52%',
'type' => 'integer',
'placeholder' => 'c0'
]
The id column is of type INTEGER, and therefore the value is being bound as such, as can be seen in your Query dump, it says 'type' => 'integer'. Being bound as an integer will cause it to be casted, and you'll end up with a comparison against 52 only.
You can workaround that by telling the query builder to treat the column as a string type. This can be done via the second argument ($types) of the query builders *where() methods:
$this->Invoices
->find()
->where(
['Invoices.id LIKE' => ($name . '%')],
['Invoices.id' => 'string']
);
See also
API > \Cake\ORM\Query::where()
In this case You can "inject" plain query - array values with numeric index in conditions are treated as plain query, and it will not be parametrized. Be carefull: Typecast to integer is necessary in this case to prevent SQL Injection:
$result = $this->Invoinces->find('all' , [
'conditions' => [
'id LIKE "'.(int)$input.'%" '
]
])
->toArray();
Try it like this:
'conditions' => ['Invoices.id LIKE' => '"' . $name . '%"']
you can still do it like this in cakephp 3
$results = $clients->find()->select(['id','email','name','accountid','created','status'])
->Where(function (QueryExp $exp, Query $q) use ($requestData) {
$orCond = $exp->or_([
new Comparison('accountid',$requestData['search']['value'],null,'LIKE'),
new Comparison('email',$requestData['search']['value'],null,'LIKE'),
new Comparison('name',$requestData['search']['value'],null,'LIKE'),
new Comparison('created',$requestData['search']['value'],null,'LIKE'),
new Comparison('status',$requestData['search']['value'],null,'LIKE'),
]);
return $exp->add($orCond);
});
I have a table records and another table categories
I want to get get all the records in this categories
$all_categories = '5,6,7,8';
So I am using this code:
$query = $this->Records->find('all',[
'contain' => ['Categories']
]);
if(!empty($search)){
$query->where(['Records.title LIKE' => '%'.$search.'%']);
}
if(!empty($wilaya)){
$query->where(['Records.adresse LIKE' => '%'.$wilaya.'%']);
}
if(!empty($cat)){
$query->where(['Records.category_id =' => $cat]);
} else {
$categories_array = explode(',',$all_categories);
foreach($categories_array as $category) {
$query->where(['Records.category_id =' => $category]);
}
}
When I use this, I'm getting AND-conditions by default.
How can I get OR-conditions instead?
Use IN:
$all_categories = '5,6,7,8';
$categories_array = explode(',',$all_categories);
$query->where(['Records.category_id IN' => $categories_array]);
This should work:
$all_categories = '5,6,7,8';
$array=explode(',',$all_categories);
$query->where(['Records.category_id' => $array], ['Records.category_id' => 'integer[]']);
Note: Edited answer to add information about the column data type. Won't work without this in CakePHP 3.x.
This equals to:
$all_categories = '5,6,7,8';
$array=explode(',',$all_categories);
$query->where(['Records.category_id IN' => $array]);
See Automatically Creating IN Clauses.