Sanitize Array inside save_post - wordpress

Let's say I have array like this :
Array (
[2066] => Array (
[images_id] => 2066
[title] => title one)
[2063] => Array (
[images_id] => 2063
[title] => title two )
[2022] => Array (
[images_id] => 2022
[title] => title three )
)
or in database format like this:
a:3:{i:2066;a:2:{s:8:"image_id";s:4:"2066";s:5:"title";s:9:"Title One";}i:2063;a:2:{s:8:"image_id";s:4:"2063";s:5:"title";s:9:"Title Two";}i:2022;a:2:{s:8:"image_id";s:4:"2022";s:5:"title";s:11:"Title Three";}}
How to sanitize with esc_attr or sanitize_text_field for images_id and title ?
Any help really appreciated :)

You can sanitize the images_id and the title fields of the array with Wordpress's esc_attr() and sanitize_text_field() functions using the PHP's array_walk() like below:
<?php
$arr = array(
2066 => array (
'images_id' => 2066,
'title' => 'title one'
),
2063 => array (
'images_id' => 2063,
'title' => 'title two'
),
2022 => array (
'images_id' => 2022,
'title' => 'title three'
)
);
//Sanitizing here:
array_walk($arr, function(&$value, &$key) {
$value['images_id'] = esc_attr($value['images_id']);
$value['title'] = esc_attr($value['title']);
//--AND/OR--
$value['images_id'] = sanitize_text_field($value['images_id']);
$value['title'] = sanitize_text_field($value['title']);
});
//Now check the new array:
echo '<pre>'; print_r($arr); echo '</pre>';
?>

Related

Combination of search result($query String) with added $args does not show all posts

Below code is combination of search result($query String) with added $args.
$all_num_normal (counted posts quantity) says its 5 posts as I expected. However, when I foreach title of posts, it shows only 3 titles. print_r also shows only 3 posts information.
When I search same keyword by regular search function, it shows 5 posts(its hit any of title, text, category name or meta value).
<?php
global $query_string;
$args = $query_string;
parse_str( $args, $args );
$args_normal = $args + array(
'posts_per_page' => -1,
'category_name' => $shop_name,
'category__not_in' => array( 3, 137, 571 ),
'meta_query' => array(
array(
'key'=> '2a',
'value' => array('2020-02-01' , $week),
'compare' => 'BETWEEN',
'type' => 'DATE',
),
),
);
echo '<pre>' . print_r( $args_normal, TRUE ) . '</pre>';
$query = new WP_Query($args_normal);
$all_num_normal = $query->found_posts;
?>
<?php
//Must be 5 titles, but its only 3 titles shown
$my_posts = get_posts($args_normal);
//print_r shows information of 3 posts
if ( $my_posts ) {
foreach( $my_posts as $post ) {
echo get_the_title( $post->ID);
}}
?>
print_r shows below text.
Array
(
[s] => rabbit
[posts_per_page] => -1
[category_name] => atsugi
[category__not_in] => Array
(
[0] => 3
[1] => 137
[2] => 571
)
[meta_query] => Array
(
[0] => Array
(
[key] => 2a
[value] => Array
(
[0] => 2020-02-01
[1] => 2020-07-20
)
[compare] => BETWEEN
[type] => DATE
)
)
)
I set 'suppress_filters' => false, and then filtering started correctly.
Regarding 'suppress_filters,' get_post function has default parameter "true", and it means filtering is not enable.

Problem with custom taxonomies using wp_insert_post()

I have an array Im passing to the tax_input argument in wp_insert_post(). Below is a result of printing the wp_insert_post() arguments.
[tax_input] => Array
(
[knpvsoftcomp] => Array
(
[0] => 1530
)
[knpvfiletype] => Array
(
[0] => 1497
)
[product_cat] => Array <-- Woo Product Categories
(
[0] => 821
[1] => 829
[2] => 1530
[3] => 908
)
[pa_designer] => Array
(
[0] => 549
)
)
Here is the function inserting the new post.
$newpostargs = [
'post_type' => 'product',
'post_title' => sanitize_text_field($this->submission['fieldvalues']['product_title']),
'post_author' => $this->currentUser->ID,
'post_content' => $this->submission['fieldvalues']['description'],
'post_status' => 'draft',
'tax_input' => $this->knpv_tax_input(),
'meta_input' => $this->knpv_meta_input()
];
$newpost = wp_insert_post($newpostargs);
Here is the function being called to create the taxonomy array.
public function knpv_tax_input(){
$taxarray = [];
$productcategories = [];
foreach ($this->submission['fieldvalues'] as $key => $value) {
//For product_categories
if (strpos($key, 'cat-parent') !== false || strpos($key, 'catchild-') !== false) {
$productcategories[] = $value;
}
//Software version
if (strpos($key, 'software') !== false) {
$taxarray['knpvsoftcomp'] = [$value];
}
//File Types
if (strpos($key, 'file-compat') !== false) {
$taxarray['knpvfiletype'] = [$value];
}
}
//Add product categories to tax array
$productcategories[] = 908;
$taxarray['product_cat'] = $productcategories;
//Supplier (Vendor) Taxonomy
$taxarray['pa_designer'] = [$this->submission['vendor']['vendor_id']];
return $taxarray;
}
All of these are custom taxonomies expect for the Woo Product Categories. However, these are the only terms being assigned to the post. Any thoughts?
Im admin on the site so all permissions are set right.
Replace '$term_id' to your term ID Hope this help you.
// Creates woocommerce product
$product = array(
'post_title' => $name,
'post_content' => '',
'post_status' => 'publish',
'post_author' => $current_user->ID,
'post_type' =>'product'
);
// Insert the post into the database
$product_ID = wp_insert_post($product);
wp_set_object_terms($product_ID, $term_id, 'product_cat')
;
//you-want-multiple-cat
$categories = [ 'Some Category', 'Some other Category' ];
// Overwrite any existing term
wp_set_object_terms( $product_id, $categories, 'product_cat' );
// Or, set last argument to true to append to existing terms
wp_set_object_terms( $product_id, $categories, 'product_cat', true );

Schedule email using wpMandrill to Wordpress

Is that possible to schedule a message using wpMandrill plugin?
I saw in this post that we can use mandrill_payload filter to change anything in the structure (following Mandrill's API , /messages/send).
How can I change the send_at parameter so that I can schedule e-mails to be sent.
Would it be something like this:
function customFilterSendAt($send_at)
{
$send_at = "2016-01-23 14:00:00";
return $send_at;
}
add_filter('mandrill_payload', 'customFilterSendAt');
Then
wp_mail($email_adress, $subj, $body );
?
I found that it is possible to schedule emails using wpMandrill. This link (check aaroneight comments) helped me.
To schedule your email using wpMandrill:
$message = array(
'subject' => $subj,
'from_name' => 'From Name',
'from_email' => 'from_email#example.com',
'to' => 'to_email#example.com',
'html' => $body,
'async' => false,
'ip_pool' => null,
'send_at' => '2016-02-24 19:45:00'
);
$sendmessage = wpMandrill::sendEmail($message);
Debugging:
echo '<pre>'.print_r($sendmessage,true).'</pre>';
Output example:
Array
(
[0] => Array
(
[email] => to_email#example.com
[status] => scheduled
[_id] => db835dfe43cd5d67b3743a30e184f84d
[reject_reason] =>
)
)
At this time, scheduled emails may only be managed via Mandrill's API, so you won't find them within Mandrill's Dashboard.
to list your scheduled emails you can use:
$url = 'https://mandrillapp.com/api/1.0/messages/list-scheduled.json';
$key = 'Your API key';
//$to = ''; // optional
$args = array(
'body' => array(
'key' => $key
)
);
$results = wp_remote_post( $url, $args );
$results = json_decode($results['body']);
Output example:
Array
(
[0] => stdClass Object
(
[_id] => 1d0xe54f3b759a1153b7a53g3321f4b6
[created_at] => 2016-02-24 19:30:13
[send_at] => 2016-02-24 19:42:00
[from_email] => from_email#example.com
[to] => to_email#example.com
[subject] => Email Subject
)
[1] => stdClass Object
(
[_id] => 1272e526f6924ba096d23146e2dxad4c
[created_at] => 2016-02-24 19:31:12
[send_at] => 2016-02-24 19:45:00
[from_email] => from_email#example.com
[to] => to_email#example.com
[subject] => Email Subject
)
)

Calculate different order status count and total cash for each order status in Woocommerce

I need to get the order total of a different status in between some days in woocommerce query. For it to loop through all orders in between some day I use the following query:
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'after' => array(
'year' => 2016,
'month' =>01,
'day' =>01,
),
'before' => array(
'year' => 2016,
'month' => 01,
'day' =>30,
),
'inclusive' => true,
),
),
);
$loop=new WP_Query($args);
By using this code I can loop through all the query and get the details correctly.
Now I need to get the details into following format
wc-shipped : Total order -> 10 total_cash -> 300$
wc- completed :
Totla order -> 34 total_cash -> 4580$
wc-cancelled : Total order ->
12 total_cash -> 100$
How can I get this detail in this format ?
I know how to get wc-shipped : Total order -> 10
For this I use:
$order_status_get[]=$order->post_status;
$order_status_get= array_count_values($order_status_get);
foreach ($order_status_get as $key => $value) {
echo $key.'->'.$value;
}
But I need the price also. For to get price I can use $order_total_array[]=$order->get_total();
But i don't know how to combine them and get the result in the desired format.
The easiest way I know...
using the WC_Admin_Report class... you can get the result array and manipulate it as you want... sample result is printed below...
include_once( WP_PLUGIN_DIR . '/woocommerce/includes/admin/reports/class-wc-admin-report.php');
$reports = new WC_Admin_Report();
$args = array(
'data' => array(
'_order_total' => array(
'type' => 'meta',
'function' => 'SUM',
'name' => 'total_cash'
),
'ID' => array(
'type' => 'post_data',
'function' => 'COUNT',
'name' => 'total_orders'
),
'post_status' => array(
'type' => 'post_data',
'function' => '',
'name' => 'status'
),
),
'where' => array(
array(
'key' => 'post_date',
'value' => date( 'Y-m-d', strtotime( '02/01/2016' ) ), // starting date
'operator' => '>'
),
array(
'key' => 'post_date',
'value' => date( 'Y-m-d', strtotime( '02/31/2016' ) ), // end date...
'operator' => '<'
),
),
'where_meta' => array(
array(
'meta_key' => 'who',
'meta_value' => 'manik',
'operator' => '='
)
),
'order_status' => array( 'cancelled', 'completed', 'shipped' ),
'group_by' => 'posts.post_status',
'query_type' => 'get_results',
);
$data = $reports->get_order_report_data($args);
print_r($data);
print something like
Array
(
[0] => stdClass Object
(
[total_cash] => 35
[total_orders] => 2
[status] => wc-cancelled
)
[1] => stdClass Object
(
[total_cash] => 315
[total_orders] => 21
[status] => wc-completed
)
[2] => stdClass Object
(
[total_cash] => 211
[total_orders] => 11
[status] => wc-shipped
)
)
then manipulate $data
//print_r($data);
//
$currency = (function_exists('get_woocommerce_currency_symbol'))?get_woocommerce_currency_symbol():'';
foreach($data as $item) {
echo sprintf('<p>%s : Total Orders %s -> Total Cash -> %s%s </p>', $item->status, $item->total_orders, $item->total_cash, $currency);
}
demo of $data. Click Execute code button.
Prints like:
wc-cancelled : Total Orders 2 -> Total Cash -> 35$
wc-completed : Total Orders 21 -> Total Cash -> 315$
wc-shipped : Total Orders 11 -> Total Cash -> 211$
I will give a solution that based on your question .
$order = new WC_Order('your order id ');
In your case
while($loop->have_posts()): $loop->the_post();
$order_id=get_the_ID();
$order = new WC_Order($order_id);
(1) get order status from order we can use $order->post_status
(2) to get order total we can use $order->get_total()
You can combine them and store it in to one array
$order_status_array[]=$order->post_status .'*'.$order->get_total();
here i combined using * , you can use your own.
so that the out put array like
Array ( [0] => wc-cancelled*64 [1] => wc-cancelled*254 [2] =>wc-cancelled*93 [3] => wc-cancelled*44 [4] => wc-cancelled*213 [5] => wc-cancelled*44)
Then use the following code to arrange this array in proper format
$new_array = [];
foreach($order_status_array as $key => $value) {
list($name, $val) = explode('*', $value);
if(array_key_exists($name, $new_array)) {
$new_array[$name]['total_cash'] += $val;
$new_array[$name]['total_order']++;
} else {
$new_array[$name]['total_cash'] = $val;
$new_array[$name]['total_order'] = 1;
}
}
now your array is ready , and it's like
Array(
[wc-cancelled] => Array(
[total_cash] => ...
[total_order] =>...
)
...
)
now use the following code
foreach ($new_array as $l=>$m){
echo $l.'Total Order:->'.$m['total_order'] .'Total Cash:->'.$m['total_cash'].'</br>';
}
. This will work . You can use other good solutions also . Try this .
so entire code is
while($loop->have_posts()): $loop->the_post();
$order_id=get_the_ID();
$order = new WC_Order($order_id);
$order_status_array[]=$order->post_status .'*'.$order->get_total();
endwhile;
$new_array = [];
foreach($order_status_array as $key => $value) {
list($name, $val) = explode('*', $value);
if(array_key_exists($name, $new_array)) {
$new_array[$name]['total_cash'] += $val;
$new_array[$name]['total_order']++;
} else {
$new_array[$name]['total_cash'] = $val;
$new_array[$name]['total_order'] = 1;
}
}
foreach ($new_array as $l=>$m){
echo $l.'Total Order:->'.$m['total_order'] .'Total Cash:->'.$m['total_cash'].'</br>';
}
If I understand your question correctly, you want all orders dumbed down to a list of rows summed by the post_status field, right?
In the end you want something like this:
$order_status = array(
'wc-shipped' => 10,
'wc-completed' => 20,
'wc-cancelled' => 30
);
I see two options:
1) Change the query to utilize posts_groupby to only return summarized columns.
2) Iterate over all the rows in the result set and summarize them by post_status manually. Use an array with the key of the status and increment the value by $order->get_total()

Woocommerce - Try to merge product data with data from custom tables

i have several custom tables and i'm using advanced custom fields (acf) with twig. These fields stored in the custom tables.
for example:
custom_table1, custom_table2, custom_table1_table2_relation and more of this.
They can be edited in the admin product panel and displays as objects in in relation with the product data.
Now i will merge those to an associative array.
i have this:
/*output*/
[post] => TimberPost Object (
[ImageClass] => TimberImage
[PostClass] => TimberPost
[object_type] => post
[class] => post-8 product type-product
[id] => 1
[post_author] => 1
[post_content] => description
[custom] => Array (
[table1-field1] => data
[table1-field2] => data
[table2_field1] => data
[table2_field] => data
)
)
and i like to have this:
$products['products'] = array(
'id' => 1,
'post_content' => 'description',
'post_title' => 'title',
'and_so_on' => 'stuff',
[ 'custom' ] => array(
'table1' => array(
'data1' => 'content',
'data2' => 'content',
),
'table2' => array(
'data1' => 'content',
'data2' => 'content',
) /*and so on*/
)
);
I've tried to extended a WC_Class and creating a action to call these in the fronted
this is just an snippet example
class WCIntegrationProductIntegration extends WC_Query {
function __construct() {
add_action( 'woocommerce_custom_product_data', array( $this->_get_custom_product_data ) );
}
public function _get_custom_product_data() {
global $woocommerce;
$custom = array_merge(
array(
/*get custom tables and data*/
'table' = $table1,
'data' array($fields),
)
);
$product = array_merge(
array(
/*get productss and data*/
'table' = $table1,
'data' array($fields),
)
);
$the_query = new WP_Query();
}
}
new WCIntegrationProductIntegration();
But i don't get it. I'm a bit in a mess
I dont know if extending WC classes is necessary, adding custom data to a WP_Post object is simple with the_posts filter.
Raw example:
add_filter( 'the_posts', function( $posts ) {
$posts[0]->custom = [ 'table1' => [] ];
return $posts;
});
add_action( 'the_post', function( $post ) {
global $product;
print_r( $post );
print_r( $product );
});
Output:
/*
WP_Post Object
(
[ID] => 99
[post_author] => 1
...
[custom] => Array
(
[table1] => Array
...
)
WC_Product_Simple Object
(
[id] => 99
[post] => WP_Post Object
(
[ID] => 99
[post_author] => 1
...
[custom] => Array
(
[table1] => Array
...
*/
I bet that WooCommerce also has its own filter for that.

Resources