Set parameters in the query based on the condition - php

I need to write a query with multiple where condition and OR condition. This OR condition is only when if $location array is not empty. So parameters are needed only when this array is not empty.
I am not sure how to write this parameter condition in this condition.
This is the query I am working on.
$qb = $this->createQueryBuilder("e")
->select(
"e.vehicleId",
"e.schemaId",
"e.location",
)
->andWhere("e.vehicleId = :vehicleId")
->andWhere("e.optionId = :optionId")
->andWhere("e.schemaId = :schemaId");
if (count($position) > 0) {
$qb->andWhere($qb->expr()->orX(
$qb->expr()->andX("e.location = :location"),
$qb->expr()->andX("e.location = :loc")
));
}
$qb->setParameters(array(
"vehicleId" => $vehicleId,
"schemaId" => $schemaId,
"location" => $position["location"],
"loc" => $position["loc"],
));

QueryBuilder has two methods to set the query parameters.
The one you are using (setParameters(array $parameters), and the simpler setParameter($parameterName, $parameterValue).
Use the latter instead of the one you are using, and you can set the parameter where you need it:
if (count($position) > 0) {
$qb->andWhere($qb->expr()->orX(
$qb->expr()->andX("e.location = :location"),
$qb->expr()->andX("e.location = :loc")
))
->setParameter('location', $position["location"])
->setParameter('loc', $position["loc"]);
}

You can create parameteR array that holds conditional parameters.
if (count($position) > 0) {
$qb->andWhere($qb->expr()->orX(
$qb->expr()->andX("e.location = :location"),
$qb->expr()->andX("e.location = :loc")
));
$parameter["location"] = $position["location"];
$parameter["loc"] = $position["loc"];
}
And then pass and merge this parameter array into setParameters method.
$qb->setParameters(array_merge(
array(
"vehicleId" => $vehicleId,
"schemaId" => $schemaId,
),
$parameters
));

Related

Is there a MySQL function to 'use existing value' during update?

Is there a way with MySQL to specify "use previous / inherit / no change / existing value"?
Rather than needing to pull the current data from the database and use it, or have a customized database function excluding editing those columns.
if(x > y) {
$role_id = 3;
} else {
$role_id = '#no-change'; // Is there a way to do this? (not proper SQL syntax)
}
$update_user = $this->db->update('users',
array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']),
'role_id' => $role_id,
), $user_id_to_edit, 'user_id');
In a case like this where the db function is using prepared statements (not shown) I can't use the column name as to reflect the current value.
Is there such a MySQL function / variable that will essentially "ignore" updating that column? (just leave the existing value)
UPDATE: Here's the Update function:
public function update($table, $data, $where_id, $column = 'user_id') {
// Check for $table or $data not set
if (( empty( $table ) || empty( $data )) || empty($data) ) {
return false;
}
// Initiate variable to append to
$placeholders ='';
// Parse data for column and placeholder names
foreach ($data as $key => $value) {
$placeholders .= sprintf('%s=:%s,', $key, $key);
}
// Trim excess commas
$placeholders = rtrim($placeholders, ',');
// Append where ID to $data
$data['where_id'] = $where_id;
// Prepary our query for binding
$stmt = $this->db->prepare("UPDATE {$table} SET {$placeholders} WHERE $column = :where_id");
// Execute the query
$stmt->execute($data);
// Check for successful insertion
if ( $stmt->rowCount() ) {
return true;
}
return false;
}
You could try this:
$data = array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']))
if(x > y) {
$data['role_id'] = 3;
}
$update_user = $this->db->update('users', $data, $user_id_to_edit, 'user_id');
That way, you can customize $data before hand if you like.
I should also mention, if you're concerned about redundancy, you can put your data sanitation inside a function. Something along the lines of:
function sanitize($data) {
if(x > y) {
$data['role_id'] = 3;
} else {
if(isset($data['role_id']) {
unset($data['role_id']);
}
}
return $data;
}
$data = array(
'first_name' => filterName($post['first_name']),
'last_name' => filterName($post['last_name']),
'email' => filterEmail($post['email']))
$update_user = $this->db->update('users', sanitize($data), $user_id_to_edit, 'user_id');
Edit: Something I should mention is that, if we're talking pure SQL, all you need to do is omit those columns from the query, so:
UPDATE table SET Col1=val1, Col2=val2, Col3=val3 WHERE id=val
But if for some reason you don't want to update Col3, just remove it from the query:
UPDATE table SET Col1=val1, Col2=val2 WHERE id=val
Since you have a function that just adds whatever you give it, you just need to sanitize the data ahead of time. That's probably the best way to do it.

Partial grouping of query result

I have a custom query in my repository that gets me results be accepting zipcodes or citynames as a value.
These values are served to an autocomplete text input.
public function findByZipOrCity($cz)
{
$qb = $this->createQueryBuilder('z');
if (substr($cz, 0, 1) == "0") {
$cz = substr($cz, 1);
$qb
->select('z')
->where($qb->expr()->orX(
$qb->expr()->like('z.city', ':czRequest'),
$qb->expr()->like('z.code', ':czRequest')
))
->andWhere('z.code <= :smaller')
->setParameter('czRequest', $cz . '%')
->setParameter('smaller', 9999);
} else {
$qb
->select('z')
->where($qb->expr()->orX(
$qb->expr()->like('z.city', ':czRequest'),
$qb->expr()->like('z.code', ':czRequest')
))
->setParameter('czRequest', $cz . '%');
}
return $qb->getQuery()->getArrayResult();
}
I work with this ArrayResult() to output JSON that the autosuggest plgin accepts:
$zipcodes = $this->getDoctrine()->getManager()->getRepository("AppBundle:Zip")->findByZipOrCity($zip);
$response = new JsonResponse();
$codes = array();
foreach ($zipcodes as $zipcode) {
$codes[] = array(
'id' => $zipcode['id'],
'country' => $zipcode['country'],
'city' => $zipcode['city'],
'code' => sprintf('%05d', $zipcode['code']),
);
}
$response->setData($codes);
return $response;
so querying for 'berli' gives the above result, the autosuggest looks like this:
This works fine, now I want to alter (any of the) function to have it displayed like this:
Which of the functions do I have to change? Can I group the query already (I need one valid zip though) or just do 'something' with the array afterwards?
Any hint highly appreciated!
You can change in array like follow:
foreach ($zipcodes as $zipcode) {
$codes[$zipcode['id']] = array(
'id' => $zipcode['id'],
'country' => $zipcode['country'],
'city' => $zipcode['city'],
'code' => sprintf('%05d', $zipcode['code']),
);
}

How do I implement search filter query using mongodb?

i have few search filter user like the following image. User can select any one two or both
these are my filters language,format and status I have written a query but its not working
$lang_id =2;
$format = ''; //user not selected
$status = ''; //user not selected
$request = $collection->find(array
( '$and' => array(
array(
'language' => $lang_id ,
),
array(
'format' => $format,
),
array(
'status' => $status,
)
)
));
I have check with or also then also its not working
if filters are empty no need to find the empty field but if it is not empty need to find the field .
Please give me a solution I am new in mongodb
Thank you
As a solution to above mentioned issue please try executing following code snippet
$lang_id = 2;
$format = ''; //user not selected
$status = ''; //user not selected
$filter=array();
if(!empty($lang_id))
{
$filter['language']=$lang_id;
}
if(!empty($format))
{
$filter['format']=$format;
}
if(!empty($status))
{
$filter['status']=$status;
}
$request = $collection->find($filter);

Unset Not Clearing Array Key/Value

I have form submission that redirects based on the results of a survey. On the landing page, I call a function to process query string, query the database and return results as an array for in-page processing.
function surveyResults() {
if($goodtogo) {
$survey = $wpdb->get_results(...,ARRAY_A);
$name_has_space = strpos(trim($q_name_field[0]),' ');
if($name_has_space === false) {
$q_first_name = $q_name_field[0];
$name_has_num = preg_match('/[0-9]/',$q_first_name);
$q_first_name = ((0 === $name_has_num) ? " ".ucfirst($q_first_name).", " : '');
} else {
$q_first_name = substr(trim($q_name_field[0]),0,$name_has_space);
$name_has_num = preg_match('/[0-9]/',$q_first_name);
$q_first_name = ((0 === $name_has_num) ? " ".ucfirst($q_first_name).", " : '');
}
$survey['name']['q_fname'] = $q_first_name;
$results = $survey;
} else {
$results = false;
}
return $results;
}
Output:
Array (
[0]=> Array (
'key' => 'value'
)
...
[n]=> Array (
'key' => 'value'
)
['name'] => Array (
[q_fname] => MyName
)
)
Which is perfect – except – each time I test the page, the $survey[0-n] results change as queried, but the $survey['name']['q_fname'] still holds the previous value MyName.
I have tried adding unset($survey['name']['q_fname']); immediately after setting $results = $survey; but that doesn't seem to make a difference. Do I need to unset($results) or use a reference &$fname...
What am I missing here?
Thanks
I'm macgregor, and I'm an idiot. Missed a critical piece of condition in the query.

Cant pass array value from codeigniter controller to view

Inside my controller, I have a line that needs to pass $content['pass_check'] to the view. It is inside an if statement that checks for validation. This I have found causes it to break. Once I move the $content['pass_check'] outside of any if statement, it works just fine passing to the view. All of the other values are passed (accounts, expense_accounts, vendors, terms). What must I do to get it to pass within this if statement. I've even tried moving it outside of the validation and it still wont set.
function create() {
require_permission("INVOICE_EDIT");
$this->load->library("form_validation");
$this->form_validation->set_rules("invoice_number", "Invoice Number", "required");
if($this->form_validation->run() !== false) {
$post = $this->input->post();
$this->session->set_userdata("create_invoice_vendor", $post['vendor_id']);
$this->session->set_userdata("create_invoice_date", $post['invoice_date']);
$invoice_number_exists = $this->invoices->count(array("invoice_number" => $post['invoice_number'])) > 0;
$post['invoice_date'] = date("Y-m-d", strtotime($post['invoice_date']));
$post['due_date'] = date("Y-m-d", strtotime($post['due_date']));
$post['date_entered'] = "now()";
$id = $this->invoices->insert_invoice($post);
$this->load->model("vendors");
if(isset($post['invoice_number'])){
$string_check= $post['invoice_number'];
$string_check= preg_replace('/\d/', '#', $string_check);
$string_check= preg_replace('/\w/', '#', $string_check);
$invoice_pattern=array();
$invoice_pattern = $this->db->select("invoice_pattern")->where("vendor_id",
$post['vendor_id'])->get("vendors")->result();
$invoice_pattern=$invoice_pattern[0]->invoice_pattern;
* //// THIS IS WHERE I NEED HELP ///////
if($invoice_pattern == $string_check){
***$content['post_check'] = 1;***
$this->invoices->flag_invoice($id);
};
};
$history = array(
"type" => "invoice_entered",
"comments" => "Invoice was entered",
"link" => $id,
"admin_id" => $this->user->admin_id,
"date" => "now()",
);
$this->vendors->insert_history($post['vendor_id'], $history);
if($post['flagged'] == 1) {
$this->invoices->flag_invoice($id);
}
if($invoice_number_exists) {
redirect("invoices/confirm_invoice/".$id);
} else {
// redirect("invoices/view/".$id);
redirect("invoices/create");
}
}
$content['accounts'] = $this->db->get("acct_chart_of_accounts")->result();
$content['expense_accounts'] = $this->db->get("invoice_expense_accounts")->result();
$content['vendors'] = $this->db->select("vendor_id, name, terms, override, invoice_pattern")
->order_by("name ASC")->get("vendors")->result();
$content['terms'] = $this->db->query("SELECT DISTINCT(terms) FROM vendors")->result();
}
}
$this->template['sub_heading'] = "Create";
$this->template['content'] = $this->load->view("invoices/create", $content, true);
$this->template['sidebar'] = $this->load->view("invoices/sidebar", array(), true);
$this->template['scripts'] = array("codeigniter/javascript/invoices/create.js");
$this->template['styles'][] = "codeigniter/styles/invoices/create.css";
$this->display();
}
Obviously it won't pass it to the view if the condition doesn't match, because you're only declaring the variable within the condition if it matches.
Just create $content['pass_check'] with an initial value of 0 or whatever before the conditional check first.
function create() {
...snip...
$content['pass_check'] = 0;
if($invoice_pattern == $string_check) {
$content['post_check'] = 1;
$this->invoices->flag_invoice($id);
};
...snip...
}
Let me know if this works or not please.

Categories