How to get selected columns from the database using $wpdb->get_results(); - wordpress

I'm looking for a solution in $wpdb->get_results() which is equivalent PDO::FETCH_NUM.
This is what I'm trying to achieve:
function get_data( $token, $field ){
global $wpdb;
$wpdb->show_errors();
$result = $wpdb->get_results('SELECT '.$field.' FROM ' . $this->get_table(). ' WHERE token =\''.$token.'\' ORDER BY id DESC');
return $result[0];
}
As you can see from my query above, I'm selecting specific columns from the database, but I don't know how to access selected column using $wpdb->get_results();
I would like to get the value of the $field column based on the where clause criteria.

After deep research I have gotten a solution.
Basically, this is how to get the $field column.
function get_data( $token, $field ){
global $wpdb;
$wpdb->show_errors();
$result = $wpdb->get_results('SELECT '.$field.' FROM ' . $this->get_table(). ' WHERE token =\''.$token.'\' ORDER BY id DESC');
$data = "";
foreach ($result as $key => $value) {
$data = $value->$field;
}
return $data;
}
To make it simple, let's assume you have a column called first_name, this is how to get the first_name column from the database.
function get_data( $token ){
global $wpdb;
$wpdb->show_errors();
$result = $wpdb->get_results('SELECT first_name FROM your_table_name WHERE token =\''.$token.'\' ORDER BY id DESC');
foreach ($result as $key => $value) {
echo $data = $value->first_name;
}
}

Related

Create order from existing WC_Order_Item_Product?

tldr:// how to clone an existing WC_Order_Item_Product to a new order?
I have looked through a lot of existing subscription plugins but didnt really get warm with them. So I decided to create something as a learning project. Its not for a customer, I dont expect it to be commercially successful product, but I guess its good to step up my game.
So I have created a custom table already that saves target dates and would like to create new orders from the existing WC_Order_Item_Product-Objects. By simply adding the original Object it will just move them from the old order, which is something I do not want to happen. I wonder how I could 'clone' the object and remove the protected [order_id] which would be overridden by WC_Order->add_item anyway without altering the original database entries. Maybe thats the wrong approach or a bad idea?
I have also tried to find some up2date hint on how to create a full custom WC_Order_Item_Product but was not really successful on that.
What I got atm:
function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name;
// TODO if reminder id
if ( ! $reminder_id) {
$neworders = [];
// get all reminders from db and loop through them
$aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
foreach ($aboprodukt_reminders as $item ) {
// get original order item object to abstract
$order_item = new \WC_Order_Item_Product($item->orderitem);
// get order object
$order = $order_item->get_order();
// get customer id
$customer = $order->get_customer_id();
// TODO abstract order items
// assign user, adresses if not existing yet, copy from last order
if ( ! $neworders[$customer] ) {
// check all reminders
$customer_array = $order->get_data();
$args = array(
'customer_id' => $customer,
'created_via' => 'Aboprodukt',
'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
);
$neworders[$customer] = \wc_create_order($args);
// TODO Shipping
}
// add order items
$neworders[$customer]->add_item($order_item);
$neworders[$customer]->calculate_totals();
$neworders[$customer]->save();
}
return print_r($neworders,true);}
Not sure if it helps so. but this is the way I've managed to do so.
For understanding: I got an extra "reminder"-table in the database that stores: date, order-item-id. It is removed after its used to create a new order.
function update ($reminder_id = null) {
global $woocommerce;
global $wpdb;
global $aboprodukt_table_name;
// TODO if order id
if ( ! $reminder_id) {
$neworders = [];
// get all reminders from db and loop through them
$aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC');
foreach ($aboprodukt_reminders as $item ) {
// get original order item object to abstract
$order_item = new \WC_Order_Item_Product($item->orderitem);
$order = $order_item->get_order();
$customer = $order->get_customer_id();
// assign user, adresses if not existing yet, copy from last order
if ( ! $neworders[$customer] ) {
// check all reminders
$args = array(
'customer_id' => $customer,
'created_via' => 'Aboprodukt',
'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'),
);
$neworders[$customer] = \wc_create_order($args);
// order
$customer_object = new \WC_Customer( $customer );
$types = array('billing','shipping');
foreach ($types as $type) {
foreach ( $customer_object->{"get_{$type}"}() as $key => $value) {
if ( ! empty($value) ) {
if ( is_callable( array( $neworders[$customer], "set_{$type}_{$key}" ) ) ) {
$neworders[$customer]->{"set_{$type}_{$key}"}( $value );
}
}
}
}
// Set Shipping
$shippingold = $order->get_shipping_methods();
$oldshippingitem = new \WC_Order_Item_Shipping( reset($shippingold) );
$newshippingitem = new \WC_Order_Item_Shipping();
$newshippingitem->set_method_id( $oldshippingitem->get_method_id() );
$newshippingitem->set_instance_id( $oldshippingitem->get_instance_id() );
$newshippingitem->set_method_title( $oldshippingitem->get_method_title() );
$newshippingitem->set_total( $oldshippingitem->get_total() );
$neworders[$customer]->add_item( $newshippingitem );
}
// if variation_id > 0 then is simple product, get product
$item_variation_id = $order_item->get_variation_id();
$item_id = $neworders[$customer]->add_product(
wc_get_product(isset( $item_variation_id ) && $item_variation_id > 0 ? $item_variation_id : $order_item->get_product_id() ),
$order_item->get_quantity()
);
// copy metadata for future use
$neworderitem = new \WC_Order_Item_Product($item_id);
$neworderitem->add_meta_data( '_aboprodukt_order', $order_item->get_meta('_aboprodukt_order'), true );
$neworderitem->add_meta_data( '_aboprodukt_timespan', $order_item->get_meta('_aboprodukt_timespan'), true );
$neworderitem->add_meta_data( '_aboprodukt_type', $order_item->get_meta('_aboprodukt_type'), true );
$neworderitem->save();
$neworders[$customer]->calculate_totals();
$neworders[$customer]->save();
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $aboprodukt_table_name
WHERE id = %d",
$item->id
)
);
}
}
// send emails
foreach ( $neworders as $customers => $neworder ) {
$mailer = \WC()->mailer();
\WC()->mailer()->emails['WC_Email_Customer_Invoice']->trigger($neworder->get_id());
$neworder->add_order_note( sprintf( __('%s email notification manually sent.', 'woocommerce'), $mail->title), false, true);
}
return $neworders;
}

How to filter BuddyPress member loop by ACF field?

PHP newb here, looking for some guidance. I am working with BuddyPress and Advanced Custom Fields (ACF). I have an ACF field 'new_user' with a value of true/false. I am trying to filter my BuddyPress Members Loop to only display users with a value of 'new_user' = true.
There are 2 code samples here.
The standard BP Members Loop. My thought here, is how do I first query my users by ACF ‘new_user’ = true and then start the bp member loop?:
if ( bp_has_members() ) :
// some code goes here
endif;
while ( bp_members() ) : bp_the_member();
//OUTPUT MEMBERS LIST HERE
endwhile;
This is a BP function to filter by Buddypress extended user fields. The idea here I believe is to replace the code in the middle specific to xprofile_get_field with the proper ACF code:
function my_custom_ids( $field_name, $field_value = '' ) {
if ( empty( $field_name ) )
return '';
global $wpdb;
$field_id = xprofile_get_field_id_from_name( $field_name );
if ( !empty( $field_id ) )
$query = "SELECT user_id FROM " . $wpdb->prefix . "bp_xprofile_data WHERE field_id = " . $field_id;
else
return '';
if ( $field_value != '' )
$query .= " AND value LIKE '%" . $field_value . "%'";
/*
LIKE is slow. If you're sure the value has not been serialized, you can do this:
$query .= " AND value = '" . $field_value . "'";
*/
$custom_ids = $wpdb->get_col( $query );
if ( !empty( $custom_ids ) ) {
// convert the array to a csv string
$custom_ids_str = 'include=' . implode(",", $custom_ids);
return $custom_ids_str;
}
else
return '';
}
Of course, I am open to solving this in another way as well. I hope this is clear.

WooCommerce Get All Products as ID name pair

I am using this function to get all products as ID name pairs to populate data into a select box.
function get_product_list_as_key_name(){
$args = array( 'post_type' => 'product','posts_per_page' => -1);
$products = get_posts( $args );
$products_list = array();
if(!empty($products)){
$i = 0;
foreach ($products as $value) {
$products_list[$i]['id'] = $value->ID;
$products_list[$i]['name'] = strlen($value->post_title) > 25 ? substr(strip_tags($value->post_title), 0, 25) . "..." : $value->post_title;
$i++;
}
}
return $products_list;
}
Is there any better way to do this?(Any default function ?)
No you have to do this manually. or you can do this with custom query
function get_product_list_as_key_name(){
global $wpdb;
$query = "SELECT ID,post_title FROM {$wpdb->prefix}posts where post_type='product' AND post_status='publish'";
$products_array = $wpdb->get_results( $wpdb->prepare( $query ) );
return $products_array;
}
this is more fast then yours.

WooCommerce: Get a key=>value array of a cart items variations

This is a self Q&A
I need a way to neatly build a key=>value array of all the variations for an item in a cart. The available Woo functions all return a string.
This function takes a cart item, and returns a key=>value array.
Place it in functions.php
/*
* Get a cart product/item's variation as a key=>value pair
*/
function store_get_cart_product_variations($cart_item) {
$variations = WC()->cart->get_item_data($cart_item, true);
// Explode and trim
$parts = explode(PHP_EOL, $variations);
$parts = array_filter($parts);
// Build a key=>value pair, trim any extra whitespace
$variations = array();
foreach($parts as $part) {
list($key, $value) = explode(':', $part);
$variations[trim($key)] = trim($value);
}
return $variations;
}
And then it can be used like this:
$cart_items = WC()->cart->get_cart();
foreach ( $cart_items as $cart_item_key => $cart_item ) {
$variations = store_get_cart_product_variations($cart_item);
foreach($variations as $type => $value) {
echo $type . ': ' . '<span class="value">' . $value .'</span>';
}
}

Invalid argument for foreach associative array loop

I've got an invalid argument supplied for my last associative array foreach loop. I am looping through different email addresses and creating an array. Am I doing something wrong? Should I create a null array?
Cheers!
global $wpdb, $wpsc_variations;
$stock_table = $wpdb->prefix . 'postmeta';
$posts_table = $wpdb->prefix . 'posts';
$q = 'SELECT DISTINCT post_id FROM ' . $stock_table . ' WHERE meta_key=\'' . NOTIFY_META . '\' AND meta_value=1';
$q_assoc_arr = $wpdb->get_results($q, ARRAY_A);
foreach($q_assoc_arr as $row) {
$product_id = $row['post_id'];
$product_data = get_post_custom( $product_id );
$product_data['meta'] = maybe_unserialize( $product_data );
foreach ( $product_data['meta'] as $meta_key => $meta_value ) {
$product_data['meta'][$meta_key] = $meta_value[0];
}
if ($product_data['meta']['_wpsc_stock'] > 0) {
foreach (get_post_meta($product_id, NOTIFY_EMAILS_META, true) as $k=>$v) {
$emails[] = $v;
}
Your third foreach relies on the output of get_post_meta, but you're passing true as the 3rd parameter. This tells get_post_meta to return a single value as a string, not an array.
foreach expects an array to iterate over. :)
Note: This part will fail for certain, but your other instances of foreach may also fail if an array is not passed.

Resources