WC Marketplace Sales Report - wordpress

I have a page with the following code in it, this code is duplicated from the dashboard. This means this particular widget now shows in two places. With help I managed to increase the number of days this report shows to 60 however I only want the dashboard version to show 60 days and I would like this version to show 365 days.
<?php
/*
* The template for displaying vendor pending shipping table dashboard widget
* Override this template by copying it to yourtheme/dc-product-vendor/vendor-dashboard/dashboard-widgets/wcmp_vendor_product_sales_report.php
*
* #author WC Marketplace
* #package WCMp/Templates
* #version 3.0.0
*/
if (!defined('ABSPATH')) {
// Exit if accessed directly
exit;
}
global $WCMp;
$product_sales_report_table_headers = apply_filters('wcmp_datatable_widget_product_sales_report_table_headers', array(
'product' => array('label' => __( 'Product', 'dc-woocommerce-multi-vendor' )),
// 'revenue' => array('label' => __( 'Revenue', 'dc-woocommerce-multi-vendor' )),
'unique_purchase'=> array('label' => __( 'Unique Purchases', 'dc-woocommerce-multi-vendor' )),
), get_current_user_id());
?>
<p>This page shows all your designs that have sold over the past year.</p>
<table id="widget_product_sales_report" class="table table-striped product_sold_last_week table-bordered wcmp-widget-dt" width="100%">
<thead>
<tr>
<?php
if($product_sales_report_table_headers) :
foreach ($product_sales_report_table_headers as $key => $header) { ?>
<th class="<?php if(isset($header['class'])) echo $header['class']; ?>"><?php if(isset($header['label'])) echo $header['label']; ?></th>
<?php }
endif;
?>
<!--th><?php _e('Product', 'dc-woocommerce-multi-vendor'); ?></th>
<th><?php _e('Revenue', 'dc-woocommerce-multi-vendor'); ?></th>
<th><?php _e('Unique Purchases', 'dc-woocommerce-multi-vendor'); ?></th-->
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
jQuery(document).ready(function($) {
var product_sales_report_wgt;
var columns = [];
<?php if($product_sales_report_table_headers) {
foreach ($product_sales_report_table_headers as $key => $header) { ?>
obj = {};
obj['data'] = '<?php echo esc_js($key); ?>';
obj['className'] = '<?php if(isset($header['class'])) echo esc_js($header['class']); ?>';
columns.push(obj);
<?php }
} ?>
product_sales_report_wgt = $('#widget_product_sales_report').DataTable({
ordering : true,
paging: true,
info: true,
searching : true,
processing: false,
serverSide: true,
responsive: true,
language: {
"emptyTable": "<?php echo trim(__('Not enough data.','dc-woocommerce-multi-vendor')); ?>",
"zeroRecords": "<?php echo trim(__('Not enough data.','dc-woocommerce-multi-vendor')); ?>",
},
ajax:{
url : '<?php echo add_query_arg( 'action', 'wcmp_widget_vendor_product_sales_report', $WCMp->ajax_url() ); ?>',
type: "post",
error: function(xhr, status, error) {
$("#widget_product_sales_report tbody").append('<tr class="odd"><td valign="top" colspan="<?php if(is_array($product_sales_report_table_headers)) count($product_sales_report_table_headers); ?>" class="dataTables_empty" style="text-align:center;">'+error+' - <?php _e('Reload', 'dc-woocommerce-multi-vendor'); ?></td></tr>');
$("#widget_product_sales_report").css("display","none");
}
},
columns: columns
});
new $.fn.dataTable.FixedHeader( product_sales_report_wgt );
});
</script>
Using this code
// To change the default value of `$days_range` from 7 days to 60 days
function lh_wcmp_vendor_custom_sales_report( $days_range ) {
$days_range = 60; // you can adjust days here as you needed
return $days_range;
}
add_filter( 'wcmp_widget_vendor_product_sales_report_days_range', 'lh_wcmp_vendor_custom_sales_report', 10 );
I was able to change the default 7 days to 60. But because I am using the same widget code both the dashboard and the report show the same amount of days.
So, to summerise - what I would like is to show 60 days on the dashboard (using the code above) and then show 365 days on the report page.
Can anyone help?

You need to update the code in \basel-child\dc-product-vendor\vendor-dashboard\vendor-orders.php and \basel-child\functions.php files.
We are going to add a new query string while making the AJAX request to wcmp_widget_vendor_product_sales_report function from vendor-orders endpoint. It will allow us to detect whether the request is coming from Dashboard or Vendor Orders endpoint.
Following code will be added in the vendor-orders.php file (see line 67-79):
<?php
/* Add 'lh-endpoint' => 'lh-vendor-orders' to the AJAX URL, so we can use it later
* to change the '$days_range' value conditionally. It will change the ajax url from
* /wp-admin/admin-ajax.php?action=wcmp_widget_vendor_product_sales_report to
* /wp-admin/admin-ajax.php?action=wcmp_widget_vendor_product_sales_report&lh-endpoint=lh-vendor-orders
*/
$args = array(
'action' => 'wcmp_widget_vendor_product_sales_report',
'lh-endpoint' => 'lh-vendor-orders',
);
?>
url : '<?php echo add_query_arg( $args, $WCMp->ajax_url() ); ?>',
Then we will modify our old lh_wcmp_vendor_custom_sales_report() function in functions.php file as:
// get the value of 'lh-endpoint' from URL
$lh_orders_endpoint = isset( $_GET['lh-endpoint'] ) && !empty( $_GET['lh-endpoint'] ) ? $_GET['lh-endpoint'] : '';
// check if 'lh-endpoint' value is 'lh-vendor-orders' or not
if ( 'lh-vendor-orders' !== $lh_orders_endpoint ) {
$days_range = 60; // if 'lh-endpoint' is not 'lh-vendor-orders', then show last 2 months orders
} else {
$days_range = 365; // if 'lh-endpoint' is 'lh-vendor-orders', then show orders from 1 year
}
Here is the complete code for both files:
Remove the existing code from vendor-orders.php file and put this code:
<?php
/*
* The template for displaying vendor orders
* Override this template by copying it to yourtheme/dc-product-vendor/vendor-dashboard/vendor-orders.php
*
* #author WC Marketplace
* #package WCMp/Templates
* #version 3.0.0
*/
if (!defined('ABSPATH')) {
// Exit if accessed directly
exit;
}
global $WCMp;
$product_sales_report_table_headers = apply_filters('wcmp_datatable_widget_product_sales_report_table_headers', array(
'product' => array('label' => __( 'Product', 'dc-woocommerce-multi-vendor' )),
// 'revenue' => array('label' => __( 'Revenue', 'dc-woocommerce-multi-vendor' )),
'unique_purchase'=> array('label' => __( 'Unique Purchases', 'dc-woocommerce-multi-vendor' )),
), get_current_user_id());
?>
<p>This page shows all your designs that have sold over the past year.</p>
<table id="widget_product_sales_report" class="table table-striped product_sold_last_week table-bordered wcmp-widget-dt" width="100%">
<thead>
<tr>
<?php
if($product_sales_report_table_headers) :
foreach ($product_sales_report_table_headers as $key => $header) { ?>
<th class="<?php if(isset($header['class'])) echo $header['class']; ?>"><?php if(isset($header['label'])) echo $header['label']; ?></th>
<?php }
endif;
?>
<!--th><?php _e('Product', 'dc-woocommerce-multi-vendor'); ?></th>
<th><?php _e('Revenue', 'dc-woocommerce-multi-vendor'); ?></th>
<th><?php _e('Unique Purchases', 'dc-woocommerce-multi-vendor'); ?></th-->
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
jQuery(document).ready(function($) {
var product_sales_report_wgt;
var columns = [];
<?php if($product_sales_report_table_headers) {
foreach ($product_sales_report_table_headers as $key => $header) { ?>
obj = {};
obj['data'] = '<?php echo esc_js($key); ?>';
obj['className'] = '<?php if(isset($header['class'])) echo esc_js($header['class']); ?>';
columns.push(obj);
<?php }
} ?>
product_sales_report_wgt = $('#widget_product_sales_report').DataTable({
ordering : true,
paging: true,
info: true,
searching : true,
processing: true,
serverSide: true,
responsive: true,
language: {
"emptyTable": "<?php echo trim(__('Not enough data.','dc-woocommerce-multi-vendor')); ?>",
"zeroRecords": "<?php echo trim(__('Not enough data.','dc-woocommerce-multi-vendor')); ?>",
},
ajax:{
<?php
/* Add 'lh-endpoint' => 'lh-vendor-orders' to the AJAX URL, so we can use it later
* to change the '$days_range' value conditionally. It will change the ajax url from
* /wp-admin/admin-ajax.php?action=wcmp_widget_vendor_product_sales_report to
* /wp-admin/admin-ajax.php?action=wcmp_widget_vendor_product_sales_report&lh-endpoint=vendor-orders
*/
$args = array(
'action' => 'wcmp_widget_vendor_product_sales_report',
'lh-endpoint' => 'lh-vendor-orders',
);
?>
//url : '<?php //echo add_query_arg( 'action', 'wcmp_widget_vendor_product_sales_report', $WCMp->ajax_url() ); ?>',
url : '<?php echo add_query_arg( $args, $WCMp->ajax_url() ); ?>',
type: "post",
error: function(xhr, status, error) {
$("#widget_product_sales_report tbody").append('<tr class="odd"><td valign="top" colspan="<?php if(is_array($product_sales_report_table_headers)) count($product_sales_report_table_headers); ?>" class="dataTables_empty" style="text-align:center;">'+error+' - <?php _e('Reload', 'dc-woocommerce-multi-vendor'); ?></td></tr>');
$("#widget_product_sales_report").css("display","none");
}
},
columns: columns
});
new $.fn.dataTable.FixedHeader( product_sales_report_wgt );
});
</script>
In your functions.php file, replace the old lh_wcmp_vendor_custom_sales_report() function with the new one:
// Conditionally change the default value of `$days_range` from 7 days to 60 or 365 days
function lh_wcmp_vendor_custom_sales_report( $days_range ) {
// get the value of 'lh-endpoint' from URL
$lh_orders_endpoint = isset( $_GET['lh-endpoint'] ) && !empty( $_GET['lh-endpoint'] ) ? $_GET['lh-endpoint'] : '';
// check if 'lh-endpoint' value is 'lh-vendor-orders' or not
if ( 'lh-vendor-orders' !== $lh_orders_endpoint ) {
$days_range = 60; // if 'lh-endpoint' is not 'lh-vendor-orders', then show last 2 months orders
} else {
$days_range = 365; // if 'lh-endpoint' is 'lh-vendor-orders', then show orders from 1 year
}
return $days_range;
}
add_filter( 'wcmp_widget_vendor_product_sales_report_days_range', 'lh_wcmp_vendor_custom_sales_report' );
See the screenshots of locally hacked version of WC Marketplace plugin:
wcmp_widget_vendor_product_sales_report call from Vendor Dashboard
wcmp_widget_vendor_product_sales_report call from Vendor Orders Tab
Tested and working on:
WordPress 5.0.3
Twentyninteen 1.2
WooCommerce 3.5.4
WC Marketplace 3.3.1
Localhost (XAMPP for Windows 5.6.15)

Related

WooCommerce:: id was called incorrectly error for custom checkout fields

I'm trying to display a custom checkout field I created in functions.php for WooCommerce and I get this error (along with the actual custom field text as follows:
Notice: id was called incorrectly. Order properties should not be accessed directly. Backtrace: include('wp-admin/edit-form-advanced.php'), do_meta_boxes, WC_Meta_Box_Order_Data::output, do_action('woocommerce_admin_order_data_after_billing_address'), WP_Hook->do_action, WP_Hook->apply_filters, cdm_custom_checkout_field_display_admin_order_meta, WC_Abstract_Legacy_Order->__get, wc_doing_it_wrong Please see Debugging in WordPress for more information. (This message was added in version 3.0.) in /www/webroot/cafed/wordpress/wp-includes/functions.php on line 4778
Here's the code that is generating this error.
add_action( 'woocommerce_admin_order_data_after_billing_address', 'so_custom_checkout_field_display_admin_order_meta', 10, 1 );
function so_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Gift Message').':</strong> ' . get_post_meta( $order->id, 'Gift Message', true ) . '</p>';
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'Gift Message';
return $keys;
}
I believe this has something to do in regards to updates with Woo's code but I'm not sure how to alter it.
Similar thing i have worked on before is working for me
/**
* Add the field to the checkout
*/
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h5>'.__('Time Slot: ').'</h5>';
echo '<h6>'.__('Every Day 09:00AM - 05:00PM').'</h6>';
woocommerce_form_field( 'gv_time_slot', array(
'type' => 'hidden',
'class' => array('my-field-class form-row-wide woocommerce-validated'),
'label' => __('Every Day 04:00Pm - 09:00PM'),
'required' => false,
'placeholder' => __('Check this'),
), $checkout->get_value( 'gv_time_slot' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if (!$_POST['gv_time_slot'])
$woocommerce->add_error( __('Please enter something into this new shiny field.') );
}
/**
* Update the order meta with field value
*/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['gv_time_slot']) update_post_meta( $order_id, 'Time Slot', esc_attr($_POST['gv_time_slot']));
}
// display the extra data on order recieved page and my-account order review
function sri_display_order_data( $order_id ){ ?>
<h2><?php _e( 'Time Slot' ); ?></h2>
<table class="shop_table shop_table_responsive additional_info">
<tbody>
<tr>
<th><?php _e( 'Your Order will be delivered between' ); ?></th>
<td><?php echo 'Every Day 09:00AM - 05:00PM'; ?></td>
</tr>
<tr>
<th><?php _e( '*Please Note:' ); ?></th>
<td><?php echo 'All orders placed before 3pm in the website/WhatsApp will be delivered on the same day. Orders after 3 pm will be moved to next day.'; ?></td>
</tr>
</tbody>
</table>
<?php }
add_action( 'woocommerce_thankyou', 'sri_display_order_data', 20 );
add_action( 'woocommerce_view_order', 'sri_display_order_data', 20 );

WooCommerce Product per page Select option without reload

hi I'm trying without reload Woo-commerce Shop page product per page but its reload of selected number...
Now it's working but page reload then work I need to without reload of shop page
anybody help me
add_action('wp_head','theme_ajaxurl');
function theme_ajaxurl() {
?>
<script type="text/javascript">
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
</script>
<?php
}
add_action( 'wp_ajax_nopriv_dl_sort_by_page', 'woocommerce_catalog_per_page_ordering' );
add_action( 'wp_ajax_dl_sort_by_page', 'woocommerce_catalog_per_page_ordering' );
function woocommerce_catalog_per_page_ordering() {
?>
<form action="" method="POST" name="results">
<select name="woocommerce-sort-by-columns" id="woocommerce-sort-by-columns" class="sortby">
<?php
// This is where you can change the amounts per page that the user will use feel free to change the numbers and text as you want, in my case we had 4 products per row so I chose to have multiples of four for the user to select.
$shopCatalog_orderby = apply_filters('woocommerce_sortby_page', array(
'' => __('Products per page', 'woocommerce'),
'8' => __('8 per page', 'woocommerce'),
'16' => __('16 per page', 'woocommerce'),
'32' => __('32 per page', 'woocommerce'),
'-1' => __('View All', 'woocommerce'),
));
foreach ( $shopCatalog_orderby as $sort_id => $sort_name )
echo '<option value="' . $sort_id . '" ' . selected( $_SESSION['sortby'], $sort_id, false ) . ' >' . $sort_name . '</option>';
?>
</select>
</form>
<?php // Adrian's code
if (isset($_POST['woocommerce-sort-by-columns']) && (($_COOKIE['shop_pageResults'] <> $_POST['woocommerce-sort-by-columns']))) {
$currentProductsPerPage = $_POST['woocommerce-sort-by-columns'];
} else {
$currentProductsPerPage = $_COOKIE['shop_pageResults'];
}
?>
<script type="text/javascript">
jQuery('select.sortby>option[value="<?php echo $currentProductsPerPage; ?>"]').attr('selected', true);
</script>
<?php
}
// now we set our cookie if we need to
function dl_sort_by_page($count) {
if (isset($_COOKIE['shop_pageResults'])) { // if normal page load with cookie
$count = $_COOKIE['shop_pageResults'];
}
if (isset($_POST['woocommerce-sort-by-columns'])) { //if form submitted
setcookie('shop_pageResults', $_POST['woocommerce-sort-by-columns'], time()+1209600, '/', 'yourdomain.com', false); //this will fail if any part of page has been output- hope this works!
$count = $_POST['woocommerce-sort-by-columns'];
}
// else normal page load and no cookie
return $count;
}
add_filter('loop_shop_per_page','dl_sort_by_page');
Script Code
<script>
jQuery( document ).on( 'change', '#woocommerce-sort-by-columns', function(event) {
event.preventDefault();
var post_id = jQuery('select.sortby').val();
jQuery.ajax({
url : ajaxurl,
type : 'POST',
data : {
action : 'dl_sort_by_page'
},
success : function( response ) {
alert('ok');
}
});
})
</script>

How to show avatar only if it exists?

Is there any function in Wordpress that allows to hide the gravatar if id doesn't exists?
I have many authors that doesn't have a gravatar and all are displayed like this:
http://prntscr.com/98zsji
I would like to hide the default image.
I used the function validate_gravatar($email);, but it generated an error:
Fatal error: Call to undefined function validate_gravatar()
If I print $user_email it display correctly the user email.
You can use validate_gravatar which takes in the email address of the user and returns back true or false.
validate_gravatar($email); // returns true or false
How to use it in your code:
$user_email = get_the_author_meta('user_email');
if(validate_gravatar($user_email)) {
$author_avatar = get_avatar( get_the_author_meta( 'user_email', $author_id ), '78', '', get_the_author_meta( 'display_name', $author_id ) );
}
// Now just echo where ever you want the image, it will show a default image if no gravatar is present.
if(isset($author_avatar) && !empty($author_avatar)){
echo '<img src="'.$author_avatar.'" />';
}
// In your Functions.php
function validate_gravatar($email) {
$hash = md5(strtolower(trim($email)));
$uri = 'http://www.gravatar.com/avatar/' . $hash . '?d=404';
$headers = #get_headers($uri);
if (!preg_match("|200|", $headers[0])) {
$has_valid_avatar = FALSE;
} else {
$has_valid_avatar = TRUE;
}
return $has_valid_avatar;
}
Here is the filter that will do the trick:
function ns_filter_avatar($avatar, $id_or_email, $size, $default, $alt, $args)
{
$headers = #get_headers( $args['url'] );
if( ! preg_match("|200|", $headers[0] ) ) {
return;
}
return $avatar;
}
add_filter('get_avatar','ns_filter_avatar', 10, 6);
To work you have to add value 404 as third argument $default to get_avatar(). Example:
get_avatar( $user_email, 45, '404' )
I have been using the code below for a while and always work for me. The code is checked with PHPCS and WordPress Theme Standards and there is no errors or warnings.
The script profile-image.js is only enqueued on the respective page user-edit.php, that also applies for the media-upload and Thickbox scripts, this procedure will avoid any possible scripts conflict on your WordPress admin area.
/**
*
* Add custom user profile information
*
*/
add_action( 'show_user_profile', 'ns_show_extra_profile_fields' );
add_action( 'edit_user_profile', 'ns_show_extra_profile_fields' );
function ns_show_extra_profile_fields( $user ) { ?>
<h3>Extra profile information</h3>
<table class="form-table">
<tr>
<th><label for="image">Profile Image</label></th>
<td>
<img src="<?php echo esc_attr( get_the_author_meta( 'image', $user->ID ) ); ?>" style="height:50px;">
<input type="text" name="image" id="image" value="<?php echo esc_attr( get_the_author_meta( 'image', $user->ID ) ); ?>" class="regular-text" /><input type='button' class="button-primary" value="Upload Image" id="uploadimage"/><br />
<span class="description">Please upload your image for your profile.</span>
</td>
</tr>
</table>
<?php
}
/**
* Enqueue a script in the WordPress admin user-edit.php.
*
* #param int $pagenow Hook suffix for the current admin page.
*/
function ns_selectively_enqueue_admin_script( $hook ) {
global $pagenow;
if ($pagenow != 'user-edit.php') {
return;
}
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_enqueue_style('thickbox');
wp_register_script( 'profile-image', get_template_directory_uri().'/js/profile-image.js', array('jquery-core'), false, true );
wp_enqueue_script( 'profile-image' );
}
add_action( 'admin_enqueue_scripts', 'ns_selectively_enqueue_admin_script' );
/*
* Save custom user profile data
*
*/
add_action( 'personal_options_update', 'ns_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'ns_save_extra_profile_fields' );
function ns_save_extra_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) )
return false;
if(isset($_POST['image'])) {
$imageprofile = sanitize_text_field( wp_unslash( $_POST['image'] ) );
update_user_meta( $user_id, 'image', $imageprofile );
}
}
profile-image.js:
jQuery(document).ready(function() {
jQuery(document).find("input[id^='uploadimage']").live('click', function(){
//var num = this.id.split('-')[1];
formfield = jQuery('#image').attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
window.send_to_editor = function(html) {
imgurl = jQuery('img',html).attr('src');
jQuery('#image').val(imgurl);
tb_remove();
}
return false;
});
});

WordPress wp_enqueue_media() upload_mimes not filtering

Using the following code, I'm trying to allow only certain image types to be upload/selected with the WordPress media API. So I'm using add_filter on upload_mimes to restrict the mime types allowed. Using get_allowed_mime_types() I get an array containing only the mime types I want. However, when I click the change image button, I'm still able to upload files of mime types not listed before (such as PDF). What am I doing wrong?
public static function file_uploader( $element_id = null, $multiple = true )
{
add_filter( 'upload_mimes', array( 'JBLAB_Utils', 'images_upload_mimes' ) );
var_dump( get_allowed_mime_types() );
/**
* outputs:
* array(3) {
* ["jpg|jpeg|jpe"]=>
* string(10) "image/jpeg"
* ["gif"]=>
* string(9) "image/gif"
* ["png"]=>
* string(9) "image/png"
* }
*/
$multiple = ( $multiple === true ) ? 'true' : 'false';
wp_enqueue_script('jquery');
wp_enqueue_media();
?>
<div>
<?php
if ( empty( $element_id ) )
{
$element_id = "jblab_uploaded_file_url";
?>
<label for="jblab_uploaded_file_url"><?php _e( 'Image', 'jblab-radionomy' ); ?></label>
<input type="text" name="jblab_uploaded_file_url" id="jblab_uploaded_file_url" class="regular-text">
<?php
}
?>
<input type="button" name="jblab_upload_file_upload_btn" id="jblab_upload_upload_btn" class="button-secondary" value="<?php _e( 'Change Image', 'jblab-radionomy' ); ?>">
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#jblab_upload_upload_btn').click(function(e) {
e.preventDefault();
var image = wp.media({
title: '<?php echo str_replace( "'", "\'", __( 'Change Image', 'jblab-radionomy' ) ); ?>',
multiple: <?php echo $multiple; ?>
}).open()
.on('select', function(e){
var uploaded_image = image.state().get('selection').first();
var image_url = uploaded_image.toJSON().url;
<?php
echo "
if ($('#$element_id').is('img')) {
$('#$element_id').attr('src',image_url);
} else {
$('#$element_id').val(image_url);
}
";
?>
});
});
});
</script>
<?php
}
public static function images_upload_mimes ( $mimes = array() )
{
//unset( $mimes );
$mimes = array(
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
);
return $mimes;
}
Ok, so I found a solution to my issue.
I had to move the add_filter outside of the function that is calling the upload API. If anybody has the same problem, try to add_filters as soon as possible in the process, that should do the trick.

Datatable server side wordpress integration

So, I am inheriting an intranet site that was built on datatables. Basically it is made in Wordpress and then displays custom fields that the users have filled out in the datatable. But it was querying 40 columns per post over 2k entries so is now grinding to a standstill when the users try and view the data in the table.
I'm attempting to utilize the server-side aspect of Datatables for this, but running into a little trouble because of how the sql data is formatted.
Can anyone offer any assistance in how to set up the server_processing.php file (i'm using this one: http://datatables.net/development/server-side/php_mysql) to:
Display rows based on the wp_posts.ID index
Display columns in this row based on a different table (wp_postmeta) wherein each column value is indexed separately in the wp_postmeta table by the ID found in 1
Link entire row to a url found in the wp_posts table
If anyone has any ideas I would really appreciate it...
Definitely a plugin for WordPress is most efficient. AJAX can conflict/cause problems with the JQuery that is core to using WordPress edit functions etc. I'd go to WordPress.org and look under plugins for help there. There are also paid/premium intranet plugins such as Simple Intranet. :)
Chris
Probably you might be interested in this plugin - looks like it does exactly what you're looking for: http://wpdatatables.com
An example with server-side processing: http://wpdatatables.com/display-mysql-table-in-wordpress/
You will definitely need a Wordpress table plugin that wraps DataTables functionality. You may consider Tabulizer for Wordpress (http://www.tabulizer.com) that supports server side processing and loads table data via Ajax calls only when needed. There is also a data source cache for improved performance.
Ajax dataTable or server-side processing dataTable in WordPress or Core PHP.
HTML Code
<table id="student_table" width="100%">
<thead>
<tr>
<th>Roll No.</th>
<th>Full Name</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th>Roll No.</th>
<th>Full Name</th>
<th>Phone</th>
<th>Action</th>
</tr>
</tfoot>
</table>
jQuery code
jQuery('#student_table').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
"url": FrontendConfig.ajaxurl+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1',
type: "post",
}
});
WordPress or PHP code
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
if(empty($_GET['action']) || empty($_GET['exam_id'])){
wp_send_json_error( new \WP_Error( 'Bad Request' ) );
}
if(isset($_GET['exam_id']) && $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( $_GET['exam_nounce'], 'exam_nounce_data' )):
$exam_id = (isset($_GET['exam_id'])) ? absint($_GET['exam_id']) : '';
/*# You can create a function to get the data here */
$students = getStudentsFromExamId($exam_id);
$tdata = [];
foreach ($students as $key => $value):
$tdata[$key][] = $value->roll_no;
$tdata[$key][] = $value->name;
$tdata[$key][] = $value->phone;
$tdata[$key][] = 'action here';
endforeach;
$total_records = count($tdata);
$json_data = array(
/* $_REQUEST['draw'] comes from the datatable, you can print to ensure that */
"draw" => intval( $_REQUEST['draw'] ),
"recordsTotal" => intval( $total_records ),
"recordsFiltered" => intval( $total_records ),
"data" => $tdata
);
echo json_encode($json_data);
endif;
wp_die();
}
Custom.js
jQuery( document ).ready(function() {
alert('test');
jQuery('#employee_grid').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
url :ajax_url_object.ajax_url+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1', // json datasource
type: "POST", // type of method ,GET/POST/DELETE
error: function(){
jQuery("#employee_grid_processing").css("display","none");
}
}
}); });
WordPress or PHP code
function theme_styles1()
{
$template_dir_uri =content_url();
$pluginurl =plugins_url();
//====================js
wp_enqueue_style( 'vpn-custom-style1','https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.css', true );
wp_enqueue_style( 'vpn-custom-boostrap1','https://cdn.datatables.net/1.11.3/css/dataTables.bootstrap4.min.css', true );
wp_enqueue_script( 'vpn-script11','https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js', true );
wp_enqueue_script( 'vpn-script21','https://cdn.datatables.net/1.11.3/js/dataTables.bootstrap4.min.js', true );
wp_enqueue_script( 'vpn_script31', plugin_dir_url( __FILE__ ).'js/custom.js', true );
//============ ajax url
$urls= array('ajax_url'=> admin_url( 'admin-ajax.php' ),
'site_url' => site_url()
);
wp_localize_script( 'vpn_script31', 'ajax_url_object',$urls);
}
add_action( 'wp_enqueue_scripts', 'theme_styles1',99 );
div class="wrap">
<h1>Service List</h1>
<div class="container">
<table id="employee_grid" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>Empid</th>
<th>Name</th>
<th>Salary</th>
<th>Age</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Empid</th>
<th>Name</th>
<th>Salary</th>
<th>Age</th>
</tr>
</tfoot>
</table>
</div>
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
global $wp;
$servername = "localhost:3308";
$username = "root";
$password = "";
$dbname = "demo";
$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
$params = $columns = $totalRecords = $data = array();
$params = $_REQUEST;
// echo "<pre>";
// print_r($params);
// die;
//define index of column
$columns = array(
0 =>'id',
1 =>'employee_name',
2 => 'employee_salary',
3 => 'employee_age'
);
$where = $sqlTot = $sqlRec = "";
// check search value exist
if( !empty($params['search']['value']) ) {
$where .=" WHERE ";
$where .=" ( employee_name LIKE '".$params['search']['value']."%' ";
$where .=" OR employee_salary LIKE '".$params['search']['value']."%' ";
$where .=" OR employee_age LIKE '".$params['search']['value']."%' )";
}
// getting total number records without any search
$sql = "SELECT * FROM `employee` ";
$sqlTot .= $sql;
$sqlRec .= $sql;
//concatenate search sql if value exist
if(isset($where) && $where != '') {
$sqlTot .= $where;
$sqlRec .= $where;
}
$sqlRec .= " ORDER BY ". $columns[$params['order'][0]['column']]." ".$params['order'][0]['dir']." LIMIT ".$params['start']." ,".$params['length']." ";
$queryTot = mysqli_query($conn, $sqlTot) or die("database error:". mysqli_error($conn));
$totalRecords = mysqli_num_rows($queryTot);
$queryRecords = mysqli_query($conn, $sqlRec) or die("error to fetch employees data");
//iterate on results row and create new index array of data
while( $row = mysqli_fetch_row($queryRecords) ) {
$data[] = $row;
}
// echo "<pre>";
// print_r($data);
// die;
$json_data = array(
"draw" => intval( $params['draw'] ),
"recordsTotal" => intval( $totalRecords ),
"recordsFiltered" => intval($totalRecords),
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
}

Resources