Hi Codeigniter Experts.
I'm compiling a QUERY by several calls to a function.
When it is done I'll use the QUERY to retrieve some data of course.
Each call, calls another function which gets and returns some translations which is supposed to be used in the QUERY
But it seems like that the WHERE condition in translation funciton gets concatinated by the WHERE condition which I'm compiling in the main QUERY
private function add_to_asq($field_name, $values)
{
.
.
.
.
$result = array();
foreach( $values[$last_level] as $val )
{
foreach( $val as $v )
{
$result[] = $this->db->escape( $this->asq_value_translate( $last_level, $v, $field_name ) );
}
}
$this->db->where_in( sprintf( '%1$s' , $field_name ) , implode( ',' , $result ) );
}
private function asq_value_translate( $level, $value_md5 , $field_name )
{
$this->db->select( sprintf( 'level_%1$d, level_%1$d_value' , $level ) )
->distinct()
->from('search_options_tree_view')
->where( sprintf( 'md5( level_%1$d_value ) = ' , $level ), $value_md5 )
->where( 'field_name' , $field_name );
$q = $this->db->get();
$value_name = sprintf( 'level_%1$d' , $level );
$row = $q->row(0);
$q->free_result();
return $row->$value_name;
}
and the DB complains about it
Error Number: 1054
Unknown column 'type' in 'where clause'
SELECT DISTINCT `level_1`, `level_1_value` FROM (`search_options_tree_view`) WHERE
`type` IN ('\'Forhandler\'')
AND md5( level_1_value ) = '138be735c55896dbdbea9b6c5d503b6f' AND `field_name` = 'fuel'
Filename: C:\wamp\www\system\database\DB_driver.php
Line Number: 330
As you see the type IN ('\'Forhandler\'') has not anything to with the asq_value_translation.
Do you have a suggestion?
I've thought of cloning the db-object but then I thought that I ask first and shoot later.
Thanks a lot and have a nice time.
You should use $this->db->last_query() to see what the output of your query actually is. Then take that query and run it in your db client to make sure the issue is not in codeigniter, but rather in your query.
Related
I want to call the method $wpdb->get_results(),
and I need to add parameters (WHERE clauses) to the SQL query.
The thing is, I want to build a generic function that will receive a parameters object and will generate an SQL query which includes my parameters.
So, for example, if this is my base query:
$taxis = $wpdb->get_results("SELECT * FROM $table", ARRAY_A); // base query
And these are my parameters:
$params = array(
'color' => 'blue',
'model' => 'ford'
);
It will call get_results with the following query:
SELECT * FROM $table WHERE color='blue' AND model='ford';
Is there a way to build a function that will have this behaviour?
*NOTES:
I don't know how many parameters are going to be in the parameters object nor which parameters they will be (that is why it has to be generic).
I do know, (in my case) that the only SQL CLAUSES I am going to need are WHERE =.
See the code comments for an explanation on what is happening in each step:
<?php
// make sure this doesn't come from user input, as it is inserted into the query directly
$tableName = $wpdb->prefix . "yourtable";
$columnWhitelist = array( 'color', 'model' );
$params = array(
'color' => 'blue',
'model' => 'ford'
);
// filter param keys by allowed column names defined in $columnWhitelist
$params = array_filter(
$params,
function ( $key ) use ( $columnWhitelist ) {
return in_array( $key, $columnWhitelist );
},
ARRAY_FILTER_USE_KEY
);
$whereClauseParts = array();
// put column/value pairs of $params into $placeholderValues array
$placeholderValues = array();
foreach ( $params as $column => $value) {
$whereClauseParts[] = "`$column` = %s";
$placeholderValues[] = $value;
}
// put together the WHERE clause with placeholders
$whereClause = implode(' AND ', $whereClauseParts );
// put together the whole query tring
$queryString = "SELECT * FROM `$tableName` WHERE " . $whereClause;
// you can use this to see what your prepared query will roughly look like,
// but with missing single quotes around the values
// die( vsprintf(
// $queryString,
// $placeholderValues
// ) );
$wpdb->get_results(
$wpdb->prepare(
$queryString,
$placeholderValues
)
);
I am trying to make a filter and I had a little success but is not what I want.
The code is this :
public function scopeSearch( $query , $search )
{
if ( isset( $search['facility'] ) ) {
$facilities = $search['facility'];
$query->whereHas( 'facility' ,
function ( $q ) use ( $facilities ) {
$q->where( 'facility_id' , $facilities );
}
);
}
return $query;
}
The facilities variable is an array .
What it need to do is to return an apartment or more that has the facilities that I select(or the apartment that has more facilities but has the selected facilities too),but instead I get the apartment(s) with the facilities that have at least 1 facility that an apartment has .
What I need to do to return the apartments that have the selected facilities?
Seems you may need to loop through the array using foreach() to ensure it has all members of the array:
$facilities = $search['facility'];
foreach( $facilities as $one_facilities ){
$query->whereHas( 'facility' ,
function ( $q ) use ( $one_facilities ) {
$q->where( 'facility_id' , $one_facilities );
}
);
}
You may also need to use orWhere() if you want to match on just some facilities (i.e. return results that have 2 out of 3 facilities selected).
I am using buddypress on a wordpress installation. I would like to get an array of user_ids into a variable which I can then use to manipulate, for example, list in HTML or send messages to.
I have tried using the following code. I have verified my SQL query is correct via phpmyadmin.
function my_bp_get_users_by_xprofile( $field_id, $value ) {
global $wpdb;
$user_ids = $wpdb->get_col(
$wpdb->prepare(
"
SELECT `user_id`
FROM '{$wpdb->prefix}bp_xprofile_data'
WHERE `field_id` = %d
AND `value` = %s
"
, $field_id
, $value
)
);
}
Then on the page, I want to do something like this:
$user_ids = my_bp_get_users_by_xprofile( 5, '%18%' );
echo $user_ids;
I have also verified the location of my php (bp-custom) by invoking a simple function that simply echos a string.
Where am I going wrong?
I think you're missing a return in your function, so you're calling the method but not returning anything.
function my_bp_get_users_by_xprofile( $field_id, $value ) {
global $wpdb;
$user_ids = $wpdb->get_col(
$wpdb->prepare(
"
SELECT `user_id`
FROM '{$wpdb->prefix}bp_xprofile_data'
WHERE `field_id` = %d
AND `value` = %s
"
, $field_id
, $value
)
);
// Return only if there are user_id's found
if (!empty($user_ids) {
return $user_ids;
}
// Return false if nothing found
return false;
}
Then in your template you'd need to also check if its not empty:
$user_ids = my_bp_get_users_by_xprofile( 5, '%18%' );
if ($user_ids) {
// You first need to see what the structure of the returned array is and what values the indexes have
echo $user_ids['value'];
}
I got a database running on mysql 5.7.11 and has a lot of data into a table with JSON column. I got a raw query like this one.
select * from `note`
where `note_structure_id` = 3
and JSON_EXTRACT(LCASE(data), '$._letter') = 'a'
and JSON_EXTRACT(data, '$._number') = 1
Running in sequel pro or phpmyadmin it gives me a result what i expect;
{"_letter": "A", "_number": 1}
The same query i build with laravel it gives me a result of nothing. An empty array. My code to building the same query i got this kind of code.
$result = \DB::table( 'note' )->where( 'note_structure_id', $structureId );
if( is_array( $query ) ) {
if( isset( $query['where'] ) ) {
foreach( $query['where'] AS $field => $value ) {
if( is_numeric( $value ) ) {
$result = $result->where( \DB::raw( "JSON_EXTRACT(data, '$._{$field}')" ), '=', $value );
}
else {
$result = $result->where( \DB::raw( "JSON_EXTRACT(LCASE(data), '$._{$field}')" ), '=', strtolower( $value ) );
}
}
}
}
dd($result->get());
Did anyone knows what i did wrong with my code or something. I try everything what's possible for fixing it but without result.
Thanks!
Saw you fixed it, but why not just do as a raw query, in a more traditional way. Your code is not very readable at the moment.
$results = DB::select('select * from `note` where `note_structure_id` = :id and JSON_EXTRACT(LCASE(data), `$._letter`) = :a and JSON_EXTRACT(data, `$._number`) = :number', ['id' => 3, 'a' => 'a', 'number' => 1]);
This is a web app that works when user searches for an item to add to their list and the search results show an item that has previously been added to their list.
However, if the search results find an item that has not previously been added to the user's list then the user should be able to add this new item to their list.
Here's the the first function which works for adding an item that was previously on a user's list; (note the "if ($user_item_id == 'null' ..." line... this should be calling a second function called "addToUserItems")
function addItem() {
$user_item_id = $this->uri->segment( 3 );
$master_item_id = $this->uri->segment( 4 );
$store = $this->uri->segment( 5, '' );
$user_id = $this->main_model->getMasterUser( $this->user_id );
if ( $user_item_id == 'null' ) $user_item_id = $this->main_model->addToUserItems( $master_item_id, $user_id );
$quantity = $this->main_model->addToShoppingList( $user_item_id, $store, $user_id );
$message = ( $quantity == '1' ) ? 'Added to list.' : 'On shopping list ' . $quantity . ' times.';
$message .= ' <span class="undo_button" params="unadd/' . $user_item_id . '">Undo?</span>';
$return = array(
'message' => $message,
'user_item_id' => $user_item_id,
);
echo json_encode( $return );
}
Here's the second function which should be setting "user_item_id" but apparently is not;
function addToUserItems( $master_item_id, $user_id ) {
$query = $this->db->query( "
INSERT INTO user_item ( master_item_id, user_id, custom_category, custom_name, custom_store, expires_after, on_hand )
SELECT id, " . $user_id . ", original_category, original_name, '', default_expiration, 0
FROM master_item
WHERE id = '" . $master_item_id . "'
;" );
return $this->db->insert_id();
}
Any ideas why we are seeing "user_item_id" undefined? My guess, after hours of testing assumptions, is that somehow the second function is not setting the value for $user_item_id.
It might be due to a bug: http://bugs.mysql.com/bug.php?id=9481 & http://bugs.mysql.com/bug.php?id=27033
Try splitting up the query if you can afford to.. Select the data based on master_item_id, then take that and in a separate insert query, insert it into user_item table. Finally, run last_insert_id().
$masterItem = $this->db->query('SELECT * FROM master_item WHERE master_item_id = $master_item_id');
$userItem = array();//add master item and user_id stuff
$this->db->insert('user_item',$userItem);
return $this->db->insert_id();
thanks for the suggested fixes; turns out that the user_item_id variable was not being set if the user_item_id field did not have a value. code in other file corrected to include $result['user_item_id'] = 'null'; furthermore, the addItem function above was looking for a user_item_id variable value of 'null' whereas a javascript file, not mentioned in my original question, was looking for the user_item_id variable to be null. so, we had a variable that needed to be set and code in other files which needed to look consistently for 'null' vs null.