I have a search function with multiple parameters who seems to not work everytimes on each params for exemple i tested the search query with one param "etat_paiement = 0 ",
normaly i should have no results but i still have one but in the database this record have etat_paiement = 1
where i made a mistake ? thanks a lot in advance
here the code :
$query = EngagementOrder::query();
$filters = [
'structure_engagement_id' => 'structure_id',
'saison_id' => 'saison_id',
'etat_paiement' => 'etat_paiement',
'bl_comptabilite' => 'bl_comptabilite',
];
foreach ($filters as $key => $column) {
$query->when($request->{$key}, function ($query, $value) use ($column) {
$query->where($column, $value);
});
}
$engagements = $query->paginate(10);
in my debug bar i have the query like :
select * from engagement_order limit 10 offset 0
but i run the search with the url like :
https://mydomaine/engagements?etat_paiement=0
UPDATE : here my select box :
{!! Form::select('etat_paiement', array('1' => 'Facture Réglée' , '0' => 'Facture Non Rélgée') , null , ['class' => 'form-control select2 ', 'placeholder' => 'Selectionnez un type de réglement']) !!}
The problem is with the laravel's when method. When you are passing "0" as the first argument to the when function, the below is invoked with the value as "0", which is resolving to be false in this condition: if ($value)
public function when($value, $callback, $default = null)
{
if ($value) {
return $callback($this, $value) ?: $this;
} elseif ($default) {
return $default($this, $value) ?: $this;
}
return $this;
}
Instead of using when, you can generate the query like this:
foreach ($filters as $key => $column) {
if ($request->has($key)) {
$query->where($column, $request->{$key});
}
}
If you want to use when, change your code to
foreach ($filters as $key => $column) {
$query->when($request->has($key), function ($query, $value) use ($column,$key, $request) {
$query->where($column, $request->$key);
});
}
You may try exists instead of $request->{$key} for example:
$request->exists($key)
In your case $request->{$key} is evaluating to false because etat_paiement=0 has a falsy value. On the other hand, the exists will check if the query parameter/$key is present regardless of the value.
Related
enter code hereMy question about the combination filters in laravel by using eloquent.
I am trying to filter with a combination of the following:
username
Category
Sub_category
started_at
created_at
status
I use where conditions but it not working as required.
public function filter(Request $request, User $user)
{
$user = $user->newQuery();
// Search for a user based on their name.
if ($request->has('username')) {
$user->where('name', $request->input('username'));
}
// Search for a user based on their Category.
if ($request->has('Category')) {
$user->where('Category', $request->input('Category'));
}
// Search for a user based on their Sub_category.
if ($request->has('Sub_category')) {
$user->where('Sub_category', $request->input('Sub_category'));
}
// Search for a user based on their started_at.
if ($request->has('started_at')) {
$user->where('started_at', $request->input('started_at'));
}
// Search for a user based on their status.
if ($request->has('status')) {
$user->where('status', $request->input('status'));
}
// Continue for all of the filters.
// Get the results and return them.
return $user->get();
}
You should save your where conditions to the $user variable.
$user = $user->where($dbField, $request->input($requestParam));
For improved readability, I'd suggest using a loop with all of your filtering cases.
public function filter(Request $request)
{
$users = User::query();
$filters = [
'username' => 'name',
'Category' => 'Category',
'Sub_category' => 'Sub_category',
'started_at' => 'started_at',
'status' => 'status'
];
foreach ($filters as $requestParam => $dbField){
if ($request->has($requestParam)) {
$users = $users->where($dbField, $request->input($requestParam));
}
}
return $users->get();
}
Bear in mind $request->has does not check whether the parameter value is empty, use $request->filled if you wish so.
This is My examle refer this
public function filter(Request $request)
{
$q = User::query();
$email = $request->input('email');
$username= $request->input('username');
$q->when($email,function ($query) use ($email){
$query->where('email',$email);
});
$q->when($username,function ($query) use ($username){
$query->where('username',$username);
});
$results = $q->get();
//code
}
I'm trying to update a table using Maatwebsite/Laravel-Excel.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader)
{
})->get();
if(!empty($data) && $data->count())
{
foreach ($data->toArray() as $row)
{
if(!empty($row))
{
$dataArray[] =
[
//'name' => $row['name'],
'age' => $row['age'],
'phone' => $row['phone'],
//'created_at' => $row['created_at']
];
}
if(!empty($dataArray))
{
//Item::insert($dataArray);
DB::table('items')
->where('name', $row['name'])->update($dataArray);
return view('imported')->with('success', 'Course updated');
}
}
}
}
}
But its giving error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: update items set 0 = 20 where name = james
Here's my csv
name,age,phone
James,20,888839939
Joseph,54,3444444
Hanson,30,99999999
The above is the csv file i'm trying to update.
The problem is that $dataArray is an array of arrays, so to make it work you have to loop each one:
if(!empty($dataArray)) {
foreach ($dataArray as $array) {
DB::table('items')
->where('name', $row['name'])
->update($array);
}
return view('imported')->with('success', 'Course updated');
}
But this wouldn't make much sense, because every time it would be updating the row with name = $row['name'], so you probbaly need to update the line where you set a value to the $dataArray from $dataArray[] = ... to $dataArray = ...*, so it could have a single value.
In case any body comes across this, this is how i solved it.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
Excel::load($path)->each(function (Collection $csvLine) {
DB::table('items')
->where('id', $csvLine->get('id'))
->update(['name' => $csvLine->get('name'),'phone' => $csvLine->get('phone'),'age' => $csvLine->get('age')]);
});
return view('imported')->with('success', 'Course updated');
}
}
I used the each() collection method to loop through the csv file and it won the battle.
I made a search method (GET) with some filters, the only problem that i have is when i run the search result i get the results with pagination with the adresse like :
search?q=&type_licence_id=&activite_licence_id=&structure_id=8
when i click on page 2 for exemple i have :
search?page=2
So it's display me anymore the results from the search query.
Maybe i done something wrong on my controller ? Hope someone could help me , thanks a lot in advance
here my controller :
public function search(Request $request)
{
$structure = Structure::select('num_structure', 'nom_structure' , 'id')
->get()
->mapWithKeys(function($i) {
return [$i->id => $i->num_structure.' - '.$i->nom_structure];
});
$activite = ActiviteLicencie::pluck('lb_activite' , 'id');
$type_licence = Type_licence::pluck('lb_type' , 'id');
$query = Licencies::query();
$filters = [
'type_licence_id' => 'type_licence_id',
'activite_licence_id' => 'activite_licencie_id',
'structure_id' => 'structure_id',
];
foreach ($filters as $key => $column) {
$query->when($request->{$key}, function ($query, $value) use ($column) {
$query->where($column, $value);
});
}
$licencies = $query->paginate(10);
return view('licencie/recherche', compact('licencies' , 'structure' , 'activite' , 'type_licence'));
}
I use the following in my blade template:
{{ $licencies->appends(Request::all())->links() }}
It appends all your request parameters to the pagination.
Check 'Appending To Pagination Links' on https://laravel.com/docs/5.4/pagination#displaying-pagination-results for information
You could customize the Pagination URL by
$licencies = $query->paginate(10);
$licencies->setPath($request->fullUrlWithQuery());
Docs:
https://laravel.com/docs/5.4/pagination#displaying-pagination-results
https://laravel.com/api/5.4/Illuminate/Pagination/LengthAwarePaginator.html#method_setPath
when i use following method and pass body key as fail (non defined key) and some value getting pass message in return and empty row gets inserted in table, How do I validate?
Function that I use in REST API,
function categories_POST() {
$title = $this->post('title');
$no = $this->post('no');
$id= $this->post('id');
$this->load->model('model_check');
$msg = $this->model_check->addDetails($title , $no , $id);
$this->response($msg);
}
My model,
function addDetails($x, $y, $z) {
$check = "INSERT INTO categories (title,no,id) VALUES ('$x','$y','$z')";
$query = $this->db->query($check);
if($this->db->affected_rows() > 0) {
return "pass";
} else {
return "fail";
}
}
quite honestly, you'd be better off using the query builder and (depending on what style you follow(fat/skinny controllers/models)) letting the model deal with $this->post() for processing.
Is this Phil Sturgeons/Chris A's rest server?
Something like:
function categories_post() { // doesn't need to be POST()
$this->load->model('model_check');
$msg = $this->model_check->addDetails()
if ($msg)
{
$this->response([
'status' => TRUE,
'message' => 'pass'
], REST_Controller::OK);
}
// default to fail
$this->response([
'status' => FALSE,
'message' => 'fail'
], REST_Controller::HTTP_BAD_REQUEST);
}
Your model,
function addDetails() {
// this only checks to see if they exist
if (!$this->post() || !$this->post('x') || !$this->post('y') || !$this->post('z')) {
return false;
};
$insert = array(
'x' => $this->post('x'),
'y' => $this->post('y'),
'z' => $this->post('z'),
);
if($this->db->insert('categories', $insert))
{
return true;
}
return false; // defaults to false should the db be down
}
IF you mean form_validation you can use this instead of the above.
function addDetails() {
$this->load->library('form_validation');
$this->form_validation->set_rules('x', 'X', 'required');
$this->form_validation->set_rules('y', 'Y', 'required');
$this->form_validation->set_rules('z', 'Z', 'required');
if ($this->form_validation->run() == true)
{
$insert = array(
'x' => $this->post('x'),
'y' => $this->post('y'),
'z' => $this->post('z'),
);
if($this->db->insert('categories', $insert))
{
return true;
}
}
return false; // defaults to false should the db be down
}
This is quite verbose, there's shorter ways to do it, but I'd rather make it easy to figure out.
Two ways of get post values in CodeIgniter
$title = $this->input->post('title');
$no = $this->input->post('no');
$id= $this->input->post('id');
$this->load->model('model_check');
$msg = $this->model_check->addDetails($title , $no , $id);
$this->response($msg);
or
extract($_POST);
Then direct access post name
$this->load->model('model_check');
$msg = $this->model_check->addDetails($title , $no , $id);
$this->response($msg);
Best way is directly access post values in model files (not in controller)
Don't need the pass the POST values in model function.
If you have more queries, then ask to me
I have about 50 input fields and they are all required.
Is there a easy way to check if they are all set?
So i don't have to manually put every field in my model with a validation rule of "required"?
I know this is late, but I wrote a simple function to solve this problem for myself
foreach ($request->except('_token') as $data => $value) {
$valids[$data] = "required";
}
$request->validate($valids);
Good luck!
You can use the code below. This worked for me to make all request fields required.
$request->validate([
'*' => 'required',
]);
It is currently not possible to avoid referencing each of your 50 fields inside your rules() method, as the returned array goes through this one :
/**
* Explode the rules into an array of rules.
*
* #param string|array $rules
* #return array
*/
protected function explodeRules($rules)
{
foreach ($rules as $key => &$rule)
{
$rule = (is_string($rule)) ? explode('|', $rule) : $rule;
}
return $rules;
}
You can see it in the Validator's constructor here : https://github.com/illuminate/validation/blob/master/Validator.php
foreach($req->except('_token') as $data=>$value){
$valids[$data] = "required";
}
$validator= validator($req->all(),$valids);
if ($validator->fails()) {
foreach($validator->messages()->getMessages() as $key=>$val){
$response["$key"]=$val;
}
return response()->json([
'success' => 0,
'errors' =>$response,
]);
also you can use validator from Facades like this:
try {
foreach ($request->except('_token') as $data => $value) {
$valids[$data] = "required";
}
$validator = validator($request->all(), $valids);
if ($validator->fails()) {
foreach ($validator->messages()->getMessages() as $key => $val) {
$response["$key"] = $val;
}
return redirect()->back()
->withErrors($response)
->withInput();
}
}catch(\Exception $e){
die($e->getMessage()) ;
}