$wpdb query adding extra value during update query - wordpress

I am very baffled by this problem.
The below is the very simple function to update a column by adding some more value:
public function add_user_to_new_post_sub($email, $sub_post_type) {
global $wpdb;
$add_setting = "|||".$sub_post_type;
//echo $add_setting; exit;
$wpdb->query(
"UPDATE $this->subscriptions_table
SET subscription_settings = concat(subscription_settings, '$add_setting')
WHERE user_key = '$key'"
);
}
For some reason, the $sub_post_type is always added 2 times. As an example, if the subscription_settings column has apple in it, and $sub_post_type = orange, the end result after the query would be apple|||orange|||orange. I don't understand why the extra value being added. I even did a sanity check with echo to make sure I am not passing things twice, and I am not.
Please help, I have been struggling for some time now.

I found my reason; the function was being called again through another if statement. doh

Related

if else statement gives array

I made this code to below. But it isn't working. Its giving an array.
Can somebody help me with this?
<?php
/**
*$fields['listcheckbox_1574292451270']
*/
$Extra_1 = $fields['listcheckbox_1574292451270'];
if ($Extra_1 == "1_1") {
echo ("Correct");
} elseif ($Extra_1 == "2_2") {
echo ("True");
} else {
echo ("False");
}
?>
I tried to put at the last else echo = "$1_extra"; but that gave an Array.
$fields[listcheckbox_1574292451270] is a checkbox with multiple options "1_1" & "2_2"
If this code isn't any good, can somebody help me with it?
Thanks
shouldn't that first line be:
$1_extra = $fields['listcheckbox_1574292451270'];
I think you missed the ' when accessing that array.
Edit: just noticed a few things:
if echo $1_extra; outputs Array - to see the actual values of it you either need to convert the array to a string or iterate over it. For debugging array values you can use var_dump($1_extra); which provides more information than echo does.
After that you should also see how to access the data inside your array. You can read more about working with arrays in php here: https://www.php.net/manual/en/language.types.array.php

System.data.Sqlite: Return number of affected rows no matter if Query or NonQuery is used

I'm using System.Data.SQLite ADO.NET provider for SQLite and the following Powershell code to execute queries (and nonqueries) against a Sqlite3 DB:
Function Invoke-SQLite ($DBFile,$Query) {
try {
Add-Type -Path ".\System.Data.SQLite.dll"
}
catch {
write-warning "Unable to load System.Data.SQLite.dll"
return
}
if (!$DBFile) {
throw "DB Not Found" R
Sleep 5
Exit
}
$conn = New-Object System.Data.SQLite.SQLiteConnection
$conn.ConnectionString="Data Source={0}" -f $DBFile
$conn.Open()
$cmd = $Conn.CreateCommand()
$cmd.CommandText = $Query
#$cmd.CommandTimeout = 10
$ds = New-Object system.Data.DataSet
$da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
[void]$da.fill($ds)
$cmd.Dispose()
$conn.Close()
write-host ("{0} Row(s) returned " -f ($ds.Tables[0].Rows|Measure-Object|Select -ExpandProperty Count))
return $ds.Tables[0]
}
The problem is: while it is trivial to know how many rows have been SELECTed in a query operation, the same is not true if the operation is an INSERT,DELETE or UPDATE (nonqueries)
I know I could use the ExecuteNonQuery method, but i need a generic wrapper which returns number of affected rows while being agnostic about the query it executed (as Invoke-SQLCmd would do, for example)
Is that possible?
Thanks!
A few comments before the answer:
System.data.Sqlite supports executing multiple SQL statements for one command, as long as the CommandText has each valid statements delimited by a semicolon (;). This means that there could be a mixture of queries and DML statements (i.e. INSERT, UPDATE, DELETE). The fact that you do not want to distinguish between the type of statement in $Query tells me that you are likely just passing statements blindly, so it could contain any combination of statements. Simply getting only one value (whether from a query or DML) seems too limiting.
Using a DataAdapter to fill a dataset just to get counts is inefficient. Instead, it may be better to just get a DataReader object and count the returned rows. This also allows a separate count for each query statement to be retrieved, something that gets obscured by using the DataAdapter object. (Perhaps enumerating all tables in the resultant dataset could get the same number, but I'm not certain that would always be equivalent.)
One good thing is that if you insist on using a DataAdapter, it will still execute DML statements (even though the expected result is query that returns rows). The dataset will not be changed (filled), but all statements in the command text will still affect changes in the database, so the following solution will still be useful.
Even if the code had works, I assume that the line which prints "{0} Rows returned" is meant to get a simple count, but $ds.Tables[0].Rows needs to be $ds.Tables[0].Rows.Count.
Notes about this particular solution:
The key is to call either of the sqlite SQL functions changes() or total_changes(). These can be retrieved using SQL: SELECT total_changes();. I recommend getting total_changes() before and after a command, then subtracting the difference. That will get changes for multiple statements executed by one command.
I'm not a PowerShell guru, so I tested everything in C#. Treat the code below more as pseudo code since it may need tweaking.
The code:
$conn = New-Object System.Data.SQLite.SQLiteConnection
try {
$conn.ConnectionString="Data Source={0}" -f $DBFile
$conn.Open()
$cmdCount = $Conn.CreateCommand()
$cmd = $Conn.CreateCommand()
try {
$cmdCount.CommandText = "SELECT total_changes();"
$beforeChanges = $cmdcount.ExecuteScalar()
$cmd.CommandText = $Query
$ds = New-Object System.Data.DataSet
$da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
$rows = 0
try {
[void]$da.fill($ds)
foreach ($tbl in $ds.Tables) {
$rows += $tbl.Rows.Count;
}
} catch {}
$afterChanges = $cmdcount.ExecuteScalar()
$DMLchanges = $afterChanges - $beforeChanges
$totalRowAndChanges = $rows + $DMLchanges
# $ds.Tables[0] may or may not be valid here.
# If query returned no data, no tables will exist.
} finally {
$cmdCount.Dispose()
$cmd.Dispose()
}
} finally {
$conn.Dispose()
}
Alternatively, you could eliminate the DataAdapter:
$cmd.CommandText = $Query
$rdr = $cmd.ExecuteReader()
$rows = 0
do {
while ($rdr.Read()) {
$rows++
}
} while ($rdr.NextResult())
$rdr.Close();

Multiple query are not inserting data Wordpress

I wrote a function where two insert query have. One is executed and inserting data properly. But next one is not executing. And I cant check the value i want to insert if it is set or not. How to do the stuff? EXPERT's have a look kindly. My function is given below:
add_action( 'save_post', 'cs_product_save' );
function cs_product_save( $post_id ){
global $wpdb;
$cs_product_array = $_POST['cs_product'];
$cs_product_count = count($cs_product_array);
$event_start_date = $_POST['event_start_date'];
$event_end_date = $_POST['event_end_date'];
$event_start_time = $_POST['event_start_time'];
$event_end_time = $_POST['event_end_time'];
$event_all_day = $_POST['event_all_day'];
$event_phone = $_POST['event_phone'];
$event_location = $_POST['event_location'];
$event_map = $_POST['event_map'];
$table_cause_product = "wp_cause_woocommerce_product";
$table_event_info = "wp_cause_info";
for( $i=0; $i < $cs_product_count; $i++ ){
$wpdb->insert($table_cause_product,array(
'cause_ID'=>$post_id,
'product_ID'=>$cs_product_array[$i],
'status'=>'1'
),array('%d','%d','%d'));
}
$wpdb->insert($table_event_info,array(
'cause_ID'=>$post_id,
'event_start_date'=>$event_start_date,
'event_end_date'=>$event_end_date,
'event_start_time'=>$event_start_time,
'event_end_time'=>$event_end_time,
'event_all_day'=>$event_all_day,
'event_phone'=>$event_phone,
'event_location'=>$event_location,
'event_map'=>$event_map
),array('%d','%s','%s','%s','%s','%d','%s','%s','%d'));
}
I don't see any problem here with your code. But be sure to double check your code.
The issues my be with the name of your database table names. Are you sure that $table_cause_product and $table_event_info holds the actual name of the tables? I would recommend to use $wpdb->prefix instead of harcoding table names.
In my case I would check the function in several parts.
Check the $_POST actually holds the data I want.
Use $result = $wpdb->insert( $table, $data, $format ); in all cases for debug purpose as the $result would hold the result of the operation. If its is false then I would be sure that there is definitely something wrong with the operation.
Finally I would use a wp_die() (though its not a standard way to do, but it suffices my purpose) so that I can see the dumped variable data.
One major issue you might face with your code that if the post is edited after saving then it might insert another row for same post data. Again if the post is being autosaved, you need some safeguard. I would recommend a where clause here to check the row already exists or not. If exists then you can simply update the row, or else insert the data.
Hope this might help you.

Query Posts issue in wordpress

I am a little unsure how to do a WP_Query to search a meta value of my posts. The meta data includes a persons height. So valid entries would be 5'9" or 4'11" and I need to do a Compare-Between.
To make it a bit clearer: I have a filter page. So the user can select the height between 4'0" - 5'9 or 5'9" - 5'11"
The problem is I have the ' and " symbols. I can remove these. But then it will be searching between 59 and 511 which is not going to work.
Anyone know of a work around?
Save the values in inches.
You could then set up a WP_Query or a $wpdb query to fetch your results.
Whenever you are displaying the values on the front end, you convert them back to feet and inches.
update:
function convert_to_feet( $input){
$feet = (int) ($input/12);
$inches = $input%12;
return $feet . "'" . $inches . '"';
}
echo convert_to_feet(71);

wordpress get_post_meta check if multiple values set

I've got a number of custom fields in a WP theme, and I want to check if they have values - but would like a short cut to check multiple values at once - something like this:
if ( get_post_meta ( $post->ID, "first_value", "second_value", "third_value", $single = true) !="") :
// do stuff here, as they are all set ##
else:
// do something else, as they are not all set ##
endif;
this does not throw an error, but it only checks if the first value is set - any ideas?
First note the affects of setting the $single variable to true:
If $single is set to false, or left
blank, the function returns an array
containing all values of the specified
key. If $single is set to true, the
function returns the first value of
the specified key as a string, thus you can use string compare (not in an array)
Solution 1: That being said you could then use $single=false to get an array of values, and then compare the array of values to an array of null values.
Solution 2: Or you could use several conditions in the if_else statement:
if ( get_post_meta($post->ID,"first_value",true)!="" && get_post_meta($post->ID,"second_value",true)!="" && get_post_meta($post->ID,"third_value",true)!="") :
// do stuff here, as they are all set ##
else:
// do something else, as they are not all set ##
endif;
Solution 3: You could also use nested if_then statements if you prefer those.
The question is, which solution works best for you?

Resources