Related
I have adapted the code in the Display selected variation custom fields value in WooCommerce product additional information tab post in order to be able to have custom dimension fields in both the product shipping tab area and the product variations tab area of product info. Here is my adapted code:
// Add custom fields to product shipping tab
add_action( 'woocommerce_product_options_dimensions', 'add_product_options_other_dimensions');
function add_product_options_other_dimensions(){
global $product_object;
$product_id = method_exists( $product_object, 'get_id' ) ? $product_object->get_id() : $product_object->id;
echo '</div><div class="options_group">'; // New option group
woocommerce_wp_text_input( array(
'id' => 'real_length',
'class' => 'short',
'label' => __( 'Actual Length', 'woocommerce' ),
'placeholder' => 'L',
'desc_tip' => 'true',
'description' => __( 'Product actual length (in inches).', 'woocommerce' ),
) );
woocommerce_wp_text_input( array(
'id' => 'real_width',
'class' => 'short',
'label' => __( 'Actual Width', 'woocommerce' ),
'placeholder' => 'W',
'desc_tip' => 'true',
'description' => __( 'Product actual width (in inches).', 'woocommerce' ),
) );
woocommerce_wp_text_input( array(
'id' => 'real_height',
'class' => 'short',
'label' => __( 'Actual Height', 'woocommerce' ),
'placeholder' => 'H',
'desc_tip' => 'true',
'description' => __( 'Product actual height (in inches).', 'woocommerce' ),
) );
}
// Save the custom fields values as meta data
add_action( 'woocommerce_process_product_meta', 'save_product_options_other_dimensions' );
function save_product_options_other_dimensions( $post_id ){
if( isset( $_POST['real_length'] ) )
update_post_meta( $post_id, 'real_length', esc_attr( $_POST['real_length'] ) );
if( isset( $_POST['real_width'] ) )
update_post_meta( $post_id, 'real_width', esc_attr( $_POST['real_width'] ) );
if( isset( $_POST['real_height'] ) )
update_post_meta( $post_id, 'real_height', esc_attr( $_POST['real_height'] ) );
}
// Add custom fields to product variation settings
add_action( 'woocommerce_product_after_variable_attributes','add_variation_options_other_dimensions', 10, 3 );
function add_variation_options_other_dimensions( $loop, $variation_data, $variation ){
$variation_real_length = get_post_meta($variation->ID,"real_length", true );
if( ! $variation_real_length ) $variation_real_length = "";
$variation_real_width = get_post_meta($variation->ID,"real_width", true );
if( ! $variation_real_width ) $variation_real_width = "";
$variation_real_height = get_post_meta($variation->ID,"real_height", true );
if( ! $variation_real_height ) $variation_real_height = "";
echo '<p class="form-field dimensions_field">';
woocommerce_wp_text_input( array(
'id' => 'real_length' . '_' . $loop,
'class' => 'short',
'label' => __( 'Actual Length', 'woocommerce' ),
'placeholder' => 'L',
'desc_tip' => 'true',
'description' => __( 'Product actual length (in inches).', 'woocommerce' ),
'value' => $variation_real_length
) );
woocommerce_wp_text_input( array(
'id' => 'real_width' . '_' . $loop,
'class' => 'short',
'label' => __( 'Actual Width', 'woocommerce' ),
'placeholder' => 'W',
'desc_tip' => 'true',
'description' => __( 'Product actual width (in inches).', 'woocommerce' ),
'value' => $variation_real_width
) );
woocommerce_wp_text_input( array(
'id' => '_circuit' . '_' . $loop,
'class' => 'short',
'label' => __( 'Actual Height', 'woocommerce' ),
'placeholder' => 'H',
'desc_tip' => 'true',
'description' => __( 'Product actual height (in inches).', 'woocommerce' ),
'value' => $variation_real_height
) );
echo '</p>';
}
// Save product variation custom fields values
add_action( 'woocommerce_save_product_variation','save_variation_options_other_dimensions', 10 ,2 );
function save_variation_options_other_dimensions( $variation_id, $loop ){
$the_actual_lenght = $_POST["actual_length_$loop"];
if( isset($the_actual_lenght) )
update_post_meta( $variation_id, 'the_actual_lenght', esc_attr($the_actual_lenght) );
$the_actual_width = $_POST["actual_thickness_$loop"];
if( isset($the_actual_width) )
update_post_meta( $variation_id, 'the_actual_width', esc_attr($the_actual_width) );
$the_actual_height = $_POST["actual_height_$loop"];
if( isset($the_actual_height) )
update_post_meta( $variation_id, 'the_actual_height', esc_attr($the_actual_height) );
}
I have two problems though. For one, the code seems to be a little flawed in that it does not seem to save the custom length/width/height fields under the product variation area. I have checked and the flaw is in the original post's code too.
Secondly, the answer on that post does not detail how to code this so that the inputted information can show on the front end within the Additional Product Information table of Woocommerce product listings.
My question is: how do I alter this code to get it to save the product variation fields and to get the custom field values to display on the Woocommerce Additional Information Tab?
I have been working on this solution for days now and any help would be greatly appreciated.
I ended up paying someone to solve this for me but I figured that I would post the answer here. If anyone out there is looking for a solution to add a second set of dimensions to simple product shipping area and variations area and then have that display in the additional information tab, then here is the code solution:
/**
* Plugin Name: Custom Product Fields
*/
defined('ABSPATH') || exit;
/**
* Add and show simple and variable products.
* Class NFCPF
* #package NFCPF
*/
if (!class_exists('NFCPF')) {
class NFCPF
{
/**
* Hook for call.
* NFCPF constructor.
*/
public function __construct()
{
// Add simple product fields
add_action('woocommerce_product_options_shipping', [$this, 'np_show_product_fields'], 101, 3);
add_action('woocommerce_process_product_meta', [$this, 'np_save_product_fields'], 101, 1);
// Add variable product fields.
add_action('woocommerce_product_after_variable_attributes', [$this, 'np_show_product_fields'], 101, 3);
add_action('woocommerce_save_product_variation', [$this, 'np_save_product_fields'], 101, 1);
}
/**
* Show product fields in variation and simple product.
* #param array $loop
* #param array $variation_data
* #param array $variation
*/
public function np_show_product_fields($loop, $variation_data = [], $variation = [])
{
$postId = (isset($variation->ID)) ? $variation->ID : get_the_ID();
$this->np_custom_product_fields($postId);
}
/**
* Save the simple product fields.
* #param int $postId
*/
public function np_save_product_fields($postId)
{
if (isset($postId) && $postId > 0) {
$np_product_fields = $this->np_product_fields_arr();
foreach ($np_product_fields as $key => $custom_field) {
$custom_field = (isset($custom_field['id'])) ? $custom_field['id'] : '';
$np_updated_product = (isset($_POST[$custom_field][$postId])) ? $_POST[$custom_field][$postId] : '';
update_post_meta($postId, $custom_field, $np_updated_product);
}
}
}
/**
* Product Fields Array
* #return array
*/
public function np_product_fields_arr()
{
$np_product_fields = [
[
'type' => 'input_field',
'id' => 'real_length',
'class' => 'short',
'label' => 'Actual Length',
'placeholder' => 'L',
'description' => __('Product actual length (in inches).', 'woocommerce')
],
[
'type' => 'input_field',
'id' => 'real_width',
'class' => 'short',
'label' => 'Actual Width',
'placeholder' => 'W',
'description' => __('Product actual width (in inches).', 'woocommerce')
],
[
'type' => 'input_field',
'id' => 'real_height',
'class' => 'short',
'label' => 'Actual Height',
'placeholder' => 'H',
'description' => __('Product actual height (in inches).', 'woocommerce')
]
];
return $np_product_fields;
}
/**
* Show Product Fields
* #param int $postId
*/
public function np_custom_product_fields($postId)
{
$np_product_fields = $this->np_product_fields_arr();
foreach ($np_product_fields as $key => $custom_field) {
$np_field_type = (isset($custom_field['type'])) ? $custom_field['type'] : '';
$np_action_function_name = 'np_product_' . $np_field_type;
if (method_exists($this, $np_action_function_name)) {
$this->$np_action_function_name($custom_field, $postId);
}
}
}
/**
* Dynamic input field show on product detail page
* #param array $custom_field
* #param int $postId
*/
public function np_product_input_field($custom_field, $postId)
{
$custom_input_field = [
'id' => $custom_field['id'] . '[' . $postId . ']',
'label' => $custom_field['label'],
'class' => $custom_field['class'],
'placeholder' => $custom_field['placeholder'],
'value' => get_post_meta($postId, $custom_field['id'], true)
];
if (isset($custom_field['description'])) {
$custom_input_field['desc_tip'] = true;
$custom_input_field['description'] = $custom_field['description'];
}
woocommerce_wp_text_input($custom_input_field);
}
}
new NFCPF();
}
/**
* Add data to json encoded variation form.
*
* #param array $data - this is the variation's json data
* #param object $product
* #param object $variation
* #return array
*/
function kia_available_variation($data, $product, $variation)
{
$kia_data['real_length'] = $variation->get_meta('real_length', true);
$kia_data['real_width'] = $variation->get_meta('real_width', true);
$kia_data['real_height'] = $variation->get_meta('real_height', true);
return array_merge($data, $kia_data);
}
add_filter('woocommerce_available_variation', 'kia_available_variation', 10, 3);
/**
* Add scripts to variable products.
*/
function kia_on_found_template_for_variable_add_to_cart()
{
add_action('wp_print_footer_scripts', 'kia_variable_footer_scripts', 99);
}
add_action('woocommerce_variable_add_to_cart', 'kia_on_found_template_for_variable_add_to_cart', 30);
function kia_variable_footer_scripts()
{ ?>
<script type="text/template" id="tmpl-variation-template-extra-data">
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_length extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Length (in)', 'my-text-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value">{{{ data.variation.real_length }}}</td>
</tr>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_width extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Width (in)', 'my-text-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value">{{{ data.variation.real_width }}}</td>
</tr>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_height extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Height (in)', 'my-text-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value">{{{ data.variation.real_height }}}</td>
</tr>
</script>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$('form.cart')
.on('found_variation', function (event, variation) {
template = wp.template('variation-template-extra-data');
$template_html = template({
variation: variation
});
// Remove any existing rows.
$('#tab-additional_information').find('.woocommerce-product-attributes tr.extra-data').remove();
// Add new rows.
$('#tab-additional_information').find('.woocommerce-product-attributes tbody').append($template_html);
})
.on('reset_data', function (event, variation) {
$('#tab-additional_information').find('.woocommerce-product-attributes tr.extra-data').remove();
});
});
</script>
<?php
}
// Show custom field to simple product
function np_woocommerce_product_additional_information($product)
{
if ($product->is_type('simple')) {
$product_id = $product->get_id();
$real_length = get_post_meta($product_id, 'real_length', true);
$real_width = get_post_meta($product_id, 'real_width', true);
$real_height = get_post_meta($product_id, 'real_height', true);
ob_start();
?>
<table class="woocommerce-product-attributes shop_attributes">
<tbody>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_length extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Length (in)', 'np-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value"><?php echo $real_length; ?></td>
</tr>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_width extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Width (in)', 'np-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value"><?php echo $real_width; ?></td>
</tr>
<tr class="woocommerce-product-attributes-item woocommerce-product-attributes-item--attribute_real_height extra-data">
<th class="woocommerce-product-attributes-item__label"><?php esc_html_e('Height (in)', 'np-domain'); ?></th>
<td class="woocommerce-product-attributes-item__value"><?php echo $real_height; ?></td>
</tr>
</tbody>
</table>
<?php
echo ob_get_clean();
}
}
add_action('woocommerce_product_additional_information', 'np_woocommerce_product_additional_information', 99, 1);
This solution is particularly useful for anyone looking to have both "shipping dimensions" (which are provided by default by Woocommerce) and "product dimensions" which would be displayed to the customer.
In the meantime you have answered your question yourself (+1) but for the first part of your question:
"For one, the code seems to be a little flawed in that it does not seem to save the custom length/width/height fields under the product variation area. I have checked and the flaw is in the original post's code too."
This may be useful for you or other users
To add custom fields to the product shipping tab you can use:
// Add custom fields to product shipping tab
function action_woocommerce_product_options_dimensions() {
// New option group
echo '</div><div class="options_group">';
// Fields
woocommerce_wp_text_input( array(
'id' => 'real_length',
'class' => 'short',
'label' => __( 'Actual Length', 'woocommerce' ),
'placeholder' => 'L',
'desc_tip' => 'true',
'description' => __( 'Product actual length (in inches).', 'woocommerce' ),
) );
woocommerce_wp_text_input( array(
'id' => 'real_width',
'class' => 'short',
'label' => __( 'Actual Width', 'woocommerce' ),
'placeholder' => 'W',
'desc_tip' => 'true',
'description' => __( 'Product actual width (in inches).', 'woocommerce' ),
) );
woocommerce_wp_text_input( array(
'id' => 'real_height',
'class' => 'short',
'label' => __( 'Actual Height', 'woocommerce' ),
'placeholder' => 'H',
'desc_tip' => 'true',
'description' => __( 'Product actual height (in inches).', 'woocommerce' ),
) );
}
add_action( 'woocommerce_product_options_dimensions', 'action_woocommerce_product_options_dimensions' );
However, if you want to display it on 1 line then use this instead of the above code!
function action_woocommerce_product_options_dimensions() {
global $product_object;
?>
<p class="form-field actual_dimensions_field dimensions_field">
<?php /* translators: WooCommerce dimension unit*/ ?>
<label for="product_real_length"><?php printf( __( 'Actual dimensions (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ); ?></label>
<span class="wrap">
<input id="product_real_length" placeholder="<?php esc_attr_e( 'Actual length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="product_real_length" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_meta( 'product_real_length' ) ) ); ?>" />
<input id="product_real_width" placeholder="<?php esc_attr_e( 'Actual width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="product_real_width" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_meta( 'product_real_width' ) ) ); ?>" />
<input id="product_real_height" placeholder="<?php esc_attr_e( 'Actual height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="product_real_height" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_meta( 'product_real_height' ) ) ); ?>" />
</span>
<?php echo wc_help_tip( __( 'Your text', 'woocommerce' ) ); ?>
</p>
<?php
}
add_action( 'woocommerce_product_options_dimensions', 'action_woocommerce_product_options_dimensions' );
To save fields you can use the woocommerce_admin_process_product_object hook, opposite the outdated woocommerce_process_product_meta hook:
// Save the custom fields values as meta data
function action_woocommerce_admin_process_product_object( $product ) {
// When isset, save
if ( isset( $_POST['product_real_length'] ) ) {
$product->update_meta_data( 'product_real_length', esc_attr( $_POST['product_real_length'] ) );
}
if ( isset( $_POST['product_real_width'] ) ) {
$product->update_meta_data( 'product_real_width', esc_attr( $_POST['product_real_width'] ) );
}
if ( isset( $_POST['product_real_height'] ) ) {
$product->update_meta_data( 'product_real_height', esc_attr( $_POST['product_real_height'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
So far adding and saving the fields to the product shipping tab.
To add and save the fields to the variations tab area, you can use the answer below. But, here are some remarks:
The woocommerce_product_after_variable_attributes hook is replaced by woocommerce_variation_options_dimensions as it is better positioned for your question
woocommerce_admin_process_variation_object replaces the outdated woocommerce_save_product_variation
Optional: to align the fields to the left change form-row-last to form-row-first
// Add fields
function action_woocommerce_variation_options_dimensions( $loop, $variation_data, $variation ) {
global $post;
// Parent product
$product_object = wc_get_product( $post->ID );
// Get meta
$parent_length = wc_format_localized_decimal( $product_object->get_meta( 'product_real_length' ) );
$parent_width = wc_format_localized_decimal( $product_object->get_meta( 'product_real_width' ) );
$parent_height = wc_format_localized_decimal( $product_object->get_meta( 'product_real_height' ) );
$real_length = get_post_meta( $variation->ID, 'variable_real_length', true );
$real_width = get_post_meta( $variation->ID, 'variable_real_width', true );
$real_height = get_post_meta( $variation->ID, 'variable_real_height', true );
?>
<p class="form-field form-row actual_dimensions_field dimensions_field hide_if_variation_virtual form-row-last">
<label for="product_real_length">
<?php
printf(
/* translators: %s: dimension unit */
esc_html__( 'Your text (%s)', 'woocommerce' ),
esc_html( get_option( 'woocommerce_dimension_unit' ) )
);
?>
</label>
<?php echo wc_help_tip( __( 'Your text', 'woocommerce' ) ); ?>
<span class="wrap">
<input id="product_real_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Actual length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_real_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $real_length ) ); ?>" />
<input id="product_real_width" placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Actual width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_real_width[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $real_width ) ); ?>" />
<input id="product_real_height" placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Actual height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_real_height[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $real_height ) ); ?>" />
</span>
</p>
<?php
}
add_action( 'woocommerce_variation_options_dimensions', 'action_woocommerce_variation_options_dimensions', 10, 3 );
// Save
function action_woocommerce_admin_process_variation_object( $variation, $i ) {
// When isset, save
if ( isset( $_POST['variable_real_length'][$i] ) ) {
$variation->update_meta_data( 'variable_real_length', esc_attr( $_POST['variable_real_length'][$i] ) );
}
if ( isset( $_POST['variable_real_width'][$i] ) ) {
$variation->update_meta_data( 'variable_real_width', esc_attr( $_POST['variable_real_width'][$i] ) );
}
if ( isset( $_POST['variable_real_height'][$i] ) ) {
$variation->update_meta_data( 'variable_real_height', esc_attr( $_POST['variable_real_height'][$i] ) );
}
}
add_action( 'woocommerce_admin_process_variation_object', 'action_woocommerce_admin_process_variation_object', 10, 2 );
Result:
I have a WC payment gateway which was build and working until WP version 4.1. Today I started testing it on WP 4.9.8 and WC 3.5.1.
When I try to complete purchase the payment gateway is not taking me to the payment screen to fill credit card details. It get stuck on redirection state.
Hope someone can help me out to solve this.
Below the image reference and the code I am using:
<?php
/**
* Plugin Name: CustomPaymentGateway
*/
add_action('plugins_loaded', 'init_mpay', 0);
function init_mpay() {
if ( ! class_exists( 'WC_Payment_Gateway' ) ) return;
class woocommerce_mpay extends WC_Payment_Gateway {
public function __construct() {
global $woocommerce;
$this->id = 'mpay';
$this->method_title = __('MPay', 'mpay-chearaan-woo');
$this->icon = plugins_url( 'mpay.png', __FILE__ );
$this->has_fields = false;
$this->notify_url = str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'woocommerce_mpay', home_url( '/' ) ) );
// Load the form fields.
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Define user set variables
$this->mpayurl = $this->settings['mpayurl'];
$this->title = $this->settings['title'];
$this->description = $this->settings['description'];
$this->merchantid = $this->settings['merchantid'];
$this->hashKey = $this->settings['hashKey'];
$this->transactionDate = date('Y-m-d H:i:s O');
$this->woo_version = $this->get_woo_version();
// Actions
add_action('init', array(&$this, 'successful_request'));
add_action('woocommerce_api_woocommerce_mpay', array( &$this, 'successful_request' ));
add_action('woocommerce_receipt_mpay', array(&$this, 'receipt_page'));
if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) {
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ));
} else {
add_action('woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ));
}
}
/**
* Initialise Gateway Settings Form Fields
*/
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable:', 'mpay-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'Enable MPay', 'mpay-chearaan-woo' ),
'default' => 'yes'
),
'mpayurl' => array(
'title' => __( 'UAT/Production:', 'mpay-chearaan-woo' ),
'type' => 'checkbox',
'label' => __( 'UAT', 'mpay-chearaan-woo' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'The title which the user sees during checkout.', 'mpay-chearaan-woo' ),
'default' => __( 'MPay Online Payment Gateway', 'mpay-chearaan-woo' )
),
'description' => array(
'title' => __( 'Description:', 'mpay-chearaan-woo' ),
'type' => 'textarea',
'description' => __( 'Description which the user sees during checkout.', 'mpay-chearaan-woo' ),
'default' => __('Pay securely through MPay\'s Secure Servers.', 'mpay-chearaan-woo')
),
'merchantid' => array(
'title' => __( 'Merchant ID:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant ID as provided by MPay.', 'mpay-chearaan-woo' ),
'default' => ''
),
'hashKey' => array(
'title' => __( 'Merchant hashKey:', 'mpay-chearaan-woo' ),
'type' => 'text',
'description' => __( 'Please enter your Merchant hashKey as provided by MPay.', 'mpay-chearaan-woo' ),
'default' => ''
)
);
}
public function admin_options() {
?>
<h3>MPay</h3>
<p><?php _e('MPay works by sending the user to MPay to enter their payment information.', 'mpay-chearaan-woo'); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table><!--/.form-table-->
<?php
} // End admin_options()
/**
* There are no payment fields, but we want to show the description if set.
**/
function payment_fields() {
if ($this->description) echo wpautop(wptexturize($this->description));
}
/**
* Generate the button link
**/
public function generate_mpay_form( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
if ($this->mpayurl == "yes"){
$mpay_adr = "https://pcimdex.mpay.my/mdex2/payment/eCommerce";
}else{
$mpay_adr = "https://www.mdex.my/mdex/payment/eCommerce";
}
$sHash = strtoupper(hash('sha256', $this->hashKey."Continue".str_pad($this->merchantid, 10, '0', STR_PAD_LEFT).str_pad($order->id, 20, '0', STR_PAD_LEFT).str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT)));
$mpay_args = array(
'secureHash' => $sHash,
'mid' => str_pad($this->merchantid, 10, '0', STR_PAD_LEFT),
'invno' => str_pad($order->id, 20, '0', STR_PAD_LEFT),
'amt' => str_pad(($order->order_total*100), 12, '0', STR_PAD_LEFT),
'desc' => str_pad("Order No ".$order_id, 255, ' ', STR_PAD_RIGHT),
'postURL' => $this->notify_url,
'phone' => $order->billing_phone,
'email' => $order->billing_email,
'param' => 'WC|V1'
);
$mpay_args_array = array();
foreach ($mpay_args as $key => $value) {
$mpay_args_array[] = '<input type="hidden" name="'.$key.'" value="'. $value .'" /><br>';
}
wc_enqueue_js('
jQuery(function(){
jQuery("body").block(
{
message: "<img src=\"'.$woocommerce->plugin_url().'/images/uploading.gif\" alt=\"Redirecting…\" style=\"float:left; margin-right: 10px;\" />'.__('Thank you for your order. We are now redirecting you to MPay to make payment.', 'mpay-chearaan-woo').'",
overlayCSS:
{
background: "#fff",
opacity: 0.5
},
css: {
padding: 18,
textAlign: "center",
color: "#555",
border: "2px solid #aaa",
backgroundColor:"#fff",
cursor: "wait",
lineHeight: "30px"
}
});
jQuery("#submit_mpay_payment_form").click();
});
');
return '<form action="'.$mpay_adr.'" method="post">
' . implode('', $mpay_args_array) . '
<input type="submit" class="button-alt" id="submit_mpay_payment_form" value="'.__('Pay via MPay', 'mpay-chearaan-woo').'" /> <a class="button cancel" href="'.$order->get_cancel_order_url().'">'.__('Cancel order & restore cart', 'mpay-chearaan-woo').'</a>
</form>';
}
/**
* Process the payment and return the result
**/
function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
if($this->woo_version >= 2.1){
$redirect = $order->get_checkout_payment_url( true );
}else if( $this->woo_version < 2.1 ){
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}else{
$redirect = add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(get_option('woocommerce_pay_page_id'))));
}
return array(
'result' => 'success',
'redirect' => $redirect
);
}
/**
* receipt_page
**/
function receipt_page( $order ) {
echo '<p>'.__('Please click the button below to pay with MPay.', 'mpay-chearaan-woo').'</p>';
echo $this->generate_mpay_form( $order );
}
/**
* Server callback was valid, process callback (update order as passed/failed etc).
**/
function successful_request($mpay_response) {
global $woocommerce;
if (isset($_GET['wc-api']) && $_GET['wc-api'] == 'woocommerce_mpay') {
/** need to trim from result **/
$Url_result = $_GET['result'];
$order = new WC_Order( (int) substr($Url_result,7,20) );
$tranID = (int)substr($Url_result,1,6);
if (substr($Url_result,0,1) == '0'){
$r_status = 0;
}else{
$r_status = 33;
}
/*
$order = new WC_Order( (int) $_POST['invno'] );
$r_status = (int) $_POST['result'];
*/
if ($r_status == '0' ){
$order->payment_complete();
$order->add_order_note('MPay Payment was SUCCESSFUL '.'<br>AuthCode is ' . $tranID);
wp_redirect( $this->get_return_url($order) ); exit;
//wp_redirect( $this->order->get_checkout_order_received_url() ); exit;
}else{
$order->update_status('failed', sprintf(__('MPay Payment Failed. Error Communicating with Bank.', 'mpay-chearaan-woo') ) );
wp_redirect($order->get_cancel_order_url()); exit;
}
}
}
function get_woo_version() {
// If get_plugins() isn't available, require it
if ( ! function_exists( 'get_plugins' ) )
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
// Create the plugins folder and file variables
$plugin_folder = get_plugins( '/woocommerce' );
$plugin_file = 'woocommerce.php';
// If the plugin version number is set, return it
if ( isset( $plugin_folder[$plugin_file]['Version'] ) ) {
return $plugin_folder[$plugin_file]['Version'];
} else {
// Otherwise return null
return NULL;
}
}
}
}
/**
* Add the gateway to WooCommerce
**/
function add_mpay( $methods ) {
$methods[] = 'woocommerce_mpay'; return $methods;
}
add_filter('woocommerce_payment_gateways', 'add_mpay' );
I have created a custom post type for cars which I have bootstraped off this tutorial. I am having a problem where I am getting 404 returned instead of archive-car.php and single-car.php. I have also tried to add the plural versions to the template names, however, no success. What could be wrong? Am I missing something?
<?php
if( ! function_exists( 'quote_create_post_type' ) ) :
function quote_create_post_type() {
$labels = array(
'name' => 'Cars',
'singular_name' => 'Car',
'add_new' => 'Add Car',
'all_items' => 'All Cars',
'add_new_item' => 'Add Car',
'edit_item' => 'Edit car',
'new_item' => 'New car',
'view_item' => 'View car',
'search_items' => 'Search cars',
'not_found' => 'No cars found',
'not_found_in_trash' => 'No cars found in trash',
'parent_item_colon' => 'Parent car'
//'menu_name' => default to 'name'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'publicly_queryable' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array(
'title',
'editor',
'excerpt',
'thumbnail',
//'author',
//'trackbacks',
//'custom-fields',
//'comments',
'revisions',
//'page-attributes', // (menu order, hierarchical must be true to show Parent option)
//'post-formats',
),
'menu_position' => 5,
'exclude_from_search' => true,
'register_meta_box_cb' => 'quote_add_post_type_metabox'
);
register_post_type( 'car', $args );
//flush_rewrite_rules();
register_taxonomy( 'quote_category', // register custom taxonomy - category
'car',
array(
'hierarchical' => true,
'labels' => array(
'name' => 'Brands',
'singular_name' => 'Brand',
)
)
);
}
add_action( 'init', 'quote_create_post_type' );
function quote_add_post_type_metabox() { // add the meta box
add_meta_box( 'quote_metabox', 'Car Details', 'quote_metabox', 'car', 'normal' );
}
function quote_metabox() {
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="quote_post_noncename" value="' . wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
// Get the data if its already been entered
$quote_post_name = get_post_meta($post->ID, '_quote_post_name', true);
$quote_post_desc = get_post_meta($post->ID, '_quote_post_desc', true);
// Echo out the field
?>
<table class="form-table">
<tr>
<th>
<label>Brand</label>
</th>
<td>
<input type="text" name="quote_post_name" value="<?php echo $quote_post_name; ?>">
<!-- classes: .small-text .regular-text .large-text -->
</td>
</tr>
<tr>
<th>
<label>Description</label>
</th>
<td>
<textarea name="quote_post_desc" class="large-text"><?php echo $quote_post_desc; ?></textarea>
</td>
</tr>
</table>
<?php
}
function quote_post_save_meta( $post_id, $post ) { // save the data
/*
* We need to verify this came from our screen and with proper authorization,
* because the save_post action can be triggered at other times.
*/
if ( ! isset( $_POST['quote_post_noncename'] ) ) { // Check if our nonce is set.
return;
}
if( !wp_verify_nonce( $_POST['quote_post_noncename'], plugin_basename(__FILE__) ) ) { // Verify that the nonce is valid.
return $post->ID;
}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if( !wp_verify_nonce( $_POST['quote_post_noncename'], plugin_basename(__FILE__) ) ) {
return $post->ID;
}
// is the user allowed to edit the post or page?
if( ! current_user_can( 'edit_post', $post->ID )){
return $post->ID;
}
// ok, we're authenticated: we need to find and save the data
// we'll put it into an array to make it easier to loop though
$quote_post_meta['_quote_post_name'] = $_POST['quote_post_name'];
$quote_post_meta['_quote_post_desc'] = $_POST['quote_post_desc'];
// add values as custom fields
foreach( $quote_post_meta as $key => $value ) { // cycle through the $quote_post_meta array
// if( $post->post_type == 'revision' ) return; // don't store custom data twice
$value = implode(',', (array)$value); // if $value is an array, make it a CSV (unlikely)
if( get_post_meta( $post->ID, $key, FALSE ) ) { // if the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // if the custom field doesn't have a value
add_post_meta( $post->ID, $key, $value );
}
if( !$value ) { // delete if blank
delete_post_meta( $post->ID, $key );
}
}
}
add_action( 'save_post', 'quote_post_save_meta', 1, 2 ); // save the custom fields
endif; // end of function_exists()
if( ! function_exists( 'view_quotes_posts' ) ) : // output
function view_quotes_posts($do_shortcode = 1, $strip_shortcodes = 0 ) {
$args = array(
'posts_per_page' => 10,
'offset' => 0,
//'category' => ,
'orderby' => 'menu_order, post_title', // post_date, rand
'order' => 'DESC',
//'include' => ,
//'exclude' => ,
//'meta_key' => ,
//'meta_value' => ,
'post_type' => 'car',
//'post_mime_type' => ,
//'post_parent' => ,
'post_status' => 'publish',
'suppress_filters' => true
);
$posts = get_posts( $args );
$html = '';
foreach ( $posts as $post ) {
$meta_name = get_post_meta( $post->ID, '_quote_post_name', true );
$meta_desc = get_post_meta( $post->ID, '_quote_post_desc', true );
$img = get_the_post_thumbnail( $post->ID, 'medium' );
if( empty( $img ) ) {
$img = '<img src="'.plugins_url( '/img/default.png', __FILE__ ).'">';
}
if( has_post_thumbnail( $post->ID ) ) {
$img = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
$img_url = $img[0];
//the_post_thumbnail( 'thumbnail' ); /* thumbnail, medium, large, full, thumb-100, thumb-200, thumb-400, array(100,100) */
}
$content = $post->post_content;
if( $do_shortcode == 1 ) {
$content = do_shortcode( $content );
}
if( $strip_shortcodes == 1 ) {
$content = strip_shortcodes( $content );
}
$content = wp_trim_words( $content, 30, '...');
$content = wpautop( $content );
$html .= '
<div>
<h3>'.$post->post_title.'</h3>
<div>
<p>Name: '.$meta_name.'</p>
<p>Description: '.$meta_desc.'</p>
</div>
<div>'.$img.'</div>
<div>'.$content.'</div>
</div>
';
}
$html = '<div class="wrapper">'.$html.'</div>';
return $html;
}
endif; // end of function_exists()
?>
Further Info
All I am doing is extending the TwentyFifteen theme.
If I had to put money on this, I would say that you have not updated your permalinks! Simply go to Settings >> Permalinks >> Post Name.
The codex provides a little more information:
Note: In some cases, the permalink structure must be updated in order for the new template files to be accessed when viewing posts of a custom post type. To do this, go to Administration Panels > Settings > Permalinks, change the permalink structure to a different structure, save the changes, and change it back to the desired structure.
<?php
/*
Plugin Name: Opportunities
Description: Custom Post Types for "The Oppourtunities Blog" website.
Author: Sheju
Author URI: http://www.localhost.com
*/
if( ! function_exists( 'Opportunity_create_post_type' ) ) :
function Opportunity_create_post_type() {
$labels = array(
'name' => __( 'Opportunity' ),
'singular_name' => __( 'Opportunity' ),
'add_new' => __( 'Add New Opportunity' ),
'all_items' => __( 'All Opportunities' ),
'add_new_item' => __( 'Add New Opportunity' ),
'edit_item' => __( 'Edit Opportunity' ),
'new_item' => __( 'New Opportunity' ),
'view_item' => __( 'View Opportunity' ),
'search_items' => __( 'Search Opportunities' ),
'not_found' => __( 'No Opportunities found' ),
'not_found_in_trash' => __( 'No Opportunities found in trash' ),
'parent_item_colon' => __( 'Parent Opportunity' )
//'menu_name' => default to 'name'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'publicly_queryable' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array(
'title',
'editor',
'excerpt',
//'thumbnail',
//'author',
//'trackbacks',
//'custom-fields',
//'comments',
'revisions',
//'page-attributes', // (menu order, hierarchical must be true to show Parent option)
//'post-formats',
),
'taxonomies' => array( 'category', 'post_tag' ), // add default post categories and tags
'menu_position' => 5,
'register_meta_box_cb' => 'Opportunity_add_post_type_metabox'
);
register_post_type( 'Opportunity', $args );
//flush_rewrite_rules();
register_taxonomy( 'Opportunity_category', // register custom taxonomy - Opportunity category
'Opportunity',
array( 'hierarchical' => true,
'label' => __( 'Opportunity categories' )
)
);
register_taxonomy( 'Opportunity_tag', // register custom taxonomy - Opportunity tag
'Opportunity',
array( 'hierarchical' => false,
'label' => __( 'Opportunity tags' )
)
);
}
add_action( 'init', 'Opportunity_create_post_type' );
function Opportunity_add_post_type_metabox() { // add the meta box
add_meta_box( 'Opportunity_metabox', 'More Details about Opportunity', 'Opportunity_metabox', 'Opportunity', 'normal' );
}
function Opportunity_metabox() {
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="Opportunity_post_noncename" id="Opportunity_post_noncename" value="' . wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
// Get the data if its already been entered
$Opportunity_post_name = get_post_meta($post->ID, '_Opportunity_post_name', true);
$Opportunity_post_desc = get_post_meta($post->ID, '_Opportunity_post_desc', true);
$Opportunity_post_duration = get_post_meta($post->ID, '_Opportunity_post_duration', true);
// Echo out the field
?>
<div class="width_full p_box">
<p>
<label>Name<br>
<input type="text" name="Opportunity_post_name" class="widefat" value="<?php echo $Opportunity_post_name; ?>">
</label>
</p>
<p><label>Description<br>
<textarea name="Opportunity_post_desc" class="widefat"><?php echo $Opportunity_post_desc; ?></textarea>
</label>
</p>
<p><label>Duration<br>
<textarea name="Opportunity_post_duration" class="widefat"><?php echo $Opportunity_post_duration; ?></textarea>
</label>
</p>
</div>
<?php
}
function Opportunity_post_save_meta( $post_id, $post ) { // save the data
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if( !wp_verify_nonce( $_POST['Opportunity_post_noncename'], plugin_basename(__FILE__) ) ) {
return $post->ID;
}
// is the user allowed to edit the post or page?
if( ! current_user_can( 'edit_post', $post->ID )){
return $post->ID;
}
// ok, we're authenticated: we need to find and save the data
// we'll put it into an array to make it easier to loop though
$Opportunity_post_meta['_Opportunity_post_name'] = $_POST['Opportunity_post_name'];
$Opportunity_post_meta['_Opportunity_post_desc'] = $_POST['Opportunity_post_desc'];
$Opportunity_post_meta['_Opportunity_post_duration'] = $_POST['Opportunity_post_duration'];
// add values as custom fields
foreach( $Opportunity_post_meta as $key => $value ) { // cycle through the $Opportunity_post_meta array
// if( $post->post_type == 'revision' ) return; // don't store custom data twice
$value = implode(',', (array)$value); // if $value is an array, make it a CSV (unlikely)
if( get_post_meta( $post->ID, $key, FALSE ) ) { // if the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // if the custom field doesn't have a value
add_post_meta( $post->ID, $key, $value );
}
if( !$value ) { // delete if blank
delete_post_meta( $post->ID, $key );
}
}
}
add_action( 'save_post', 'Opportunity_post_save_meta', 1, 2 ); // save the custom fields
endif; // end of function_exists()
if( ! function_exists( 'view_Opportunities_posts' ) ) : // output
function view_Opportunities_posts( $num = 4, $do_shortcode = 1, $strip_shortcodes = 0 ) {
$args = array(
'numberposts' => $num,
'offset' => 0,
//'category' => ,
'orderby' => 'menu_order, post_title', // post_date, rand
'order' => 'DESC',
//'include' => ,
//'exclude' => ,
//'meta_key' => ,
//'meta_value' => ,
'post_type' => 'Opportunity',
//'post_mime_type' => ,
//'post_parent' => ,
'post_status' => 'publish',
'suppress_filters' => true
);
$posts = get_posts( $args );
$html = '';
foreach ( $posts as $post ) {
$meta_name = get_post_meta( $post->ID, '_echo"test"'.'_Opportunity_post_name', true );
$meta_desc = get_post_meta( $post->ID, '_Opportunity_post_desc', true );
$meta_duration = get_post_meta( $post->ID, '_Opportunity_post_duration', true );
/*if (!empty($meta_duration) && !empty($$meta_duration['_Opportunity_post_duration']));
*/
/*<?php $my_meta = get_post_meta($post->ID,'_my_meta',TRUE); ?>
<?php if (!empty($my_meta) && !empty($my_meta['image_one'])): ?>
<div class="archive_images_one"><img border="0" width="300px" height="200px" src="<? echo $my_meta['image_one']; ?>" alt="Android and iPhone App Development"></div>
<?php endif; ?>*/
//$img = get_the_post_thumbnail( $post->ID, 'medium' );
// if( empty( $img ) ) {
// $img = '<img src="'.plugins_url( '/img/default.png', __FILE__ ).'">';
// }
//
//
// if( has_post_thumbnail( $post->ID ) ) {
// //$image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
// //$img_url = $image[0];
// $img = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
// $img_url = $img[0];
//
// //the_post_thumbnail( 'thumbnail' ); /* thumbnail, medium, large, full, thumb-100, thumb-200, thumb-400, array(100,100) */
// }
//
$content = $post->post_content;
if( $do_shortcode == 1 ) {
$content = do_shortcode( $content );
}
if( $strip_shortcodes == 1 ) {
$content = strip_shortcodes( $content );
}
$html .= '
<div>
<h3>'.$post->post_title.'</h3>
<div>'.$content.'</div>
<div>
<p>'.$meta_name.'</p>
<p>'.$meta_desc.'</p>
<p>'.$meta_duration.'</p>
</div>
</div>
';
}
$html = '<div class="wrapper">'.$html.'</div>';
return $html;
}
endif; // end of function_exists()
?>
I need to add custom label for the meta fields in out put only if there is a value exist. Please help to do it.
I tried to change the p tag at the end (something like this):
<h3>'.$post->post_title.'</h3>
<div>
<p>Name: '.$meta_name.'</p>
<p>Description: '.$meta_desc.'</p>
</div>
<div>'.$img.'</div>
<div>'.$content.'</div>
Not 100% sure I understand what you need, but if you're looking to only show certain meta if it has a value you could do something like this:
$html .= '<div>';
$html .= '<h3>' . $post->post_title . '</h3>';
$html .= '<div>' . $content . '</div>';
$html .= '<div>';
if( !empty($meta_name) ) {
$html .= '<p>' . $meta_name . '</p>';
}
if( !empty($meta_desc) ) {
$html .= '<p>' . $meta_desc . '</p>';
}
if( !empty($meta_duration) ) {
$html .= '<p>' . $meta_duration . '</p>';
}
$html .= '</div>';
$html .= '</div>';
I am using register_post_type to create post_meta. So in its listing page by default it is showing date filter. I want remove all default filter and i want to create my new custom filter. My code to create post_type is -
//Manage news Feed
add_action('init', 'manage_news_feed');
function manage_news_feed() {
register_post_type('news_feed', array(
'labels' => array(
'name' => 'Feed Management',
'singular_name' => 'Feed Management',
'add_new' => 'Add New',
'add_new_item' => 'Add New Feed',
'edit' => 'Edit',
'edit_item' => 'Edit Feed',
'new_item' => 'New Feed',
'view' => 'View',
'view_item' => 'View Feed',
'search_items' => 'Search Feed',
'not_found' => 'No Feed',
'not_found_in_trash' => 'No Feed found in Trash',
'parent' => 'Parent News Feed'
),
'public' => true,
'menu_position' => 100,
'supports' => array('title', 'thumbnail'),
'taxonomies' => array(''),
'menu_icon' => plugins_url('images/adv-.png', __FILE__),
'has_archive' => true,
'rewrite' => true,
)
);
}
And this is to add custom column to in list page-
//Add custom column for feed_url
add_filter( 'manage_edit-news_feed_columns', 'news_feed_custom_columns', 25, 1 );
function news_feed_custom_columns( $cols )
{
$cols = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "News Feed Url",
"category_id" => "Category Id",
"date" => "Created Date"
);
return $cols;
}
add_action( 'manage_posts_custom_column', 'custom_columns', 2, 1 );
function custom_columns( $col )
{
global $post;
switch ( $col )
{
case "feed_url" :
if( '' != get_post_meta( $post->ID, 'feed_url', true ) )
echo get_post_meta( $post->ID, 'feed_url', true );
else
echo __( 'N/A', 'txt_domain' );
break;
case "category_id" :
echo get_post_meta( $post->ID, 'category_id', true );
break;
}
}
my code for Custom_meta_box is -
// Add fields for news Feed
add_action('admin_init', 'my_admin');
function my_admin() {
add_meta_box('movie_review_meta_box', 'Feed Details', 'news_feed_meta_box', 'news_feed', 'normal', 'high'
);
}
//Function to create meta_box for news feed
function news_feed_meta_box($feed) {
global $wpdb;
$category_name = esc_html(get_post_meta($feed->ID, 'category_id', true));
$feed_url = esc_html(get_post_meta($feed->ID, 'post_title', true));
?>
<table style="width: 100%">
<tr>
<td>Category Name</td>
<td><?php wp_dropdown_categories(array('hide_empty' => 0, 'name' => 'category_id', 'hierarchical' => true));?></td>
</tr>
<tr>
<td>Feed Url</td>
<td><input id="post_title" type="text" required="" data-required="true" size="40" name="post_title" value="<?php echo $feed_url; ?>" /></td>
</tr>
</table>
<?php
}
add_action('save_post', 'add_feed_fields', 10, 2);
function add_feed_fields($feed_id, $feed) {
// Check post type for feed
if ($feed->post_type == 'news_feed') {
if (isset($_POST['category_id']) && $_POST['category_id'] != '') {
update_post_meta($feed_id, 'category_id', $_POST['category_id']);
}
if (isset($_POST['feed_url']) && $_POST['feed_url'] != '') {
update_post_meta($feed_id, 'feed_url', $_POST['feed_url']);
}
}
}
i want use custom filter based on category id in list page. please help me. How i can do this.
My category filter image
If you need to add a new custom category filter you need to hook to the restrict_manage_posts filter.
Add this in your themes functions.php file.
//filter to add custom category filter and modify request
add_filter( 'restrict_manage_posts', 'custom_category_id_filter' );
add_filter( 'request', 'custom_category_id_request' );
function custom_category_id_request( $request ) {
global $post_type;
//return if we are not in wp-admin or the post type is not news_feed
if ( !is_admin() || $post_type != 'news_feed')
return $request;
//check if meta value filter is called. if then set request params
if ( isset( $_GET['mv'] ) and !empty( $_GET['mv'] )) {
$request['meta_key'] = 'category_id';
$request['meta_value'] = $_GET['mv'];
}
return $request;
}
function custom_category_id_filter( ) {
global $wpdb, $post_type;
//add this if we are in the specified post type
if ( is_admin() && $post_type == 'news_feed') {
$mvs = $wpdb->get_col( " SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = 'category_id' ORDER BY meta_value ASC " );
?>
<select name="mv">
<option value=""><?php _e( 'Show Posts from all Category ID', 'posts_meta_search' ); ?></option>
<?php
if (!empty ($mvs)) {
foreach ( $mvs as $mv ) { ?>
<option value="<?php echo esc_attr( $mv ); ?>" <?php selected( $_GET['mv'], $mv ); ?>><?php echo esc_attr( $mv ); ?></option>
<?php }
}
?>
</select>
<?php
}
}
UPDATE 1:
Since the meta_value column is varchar field you need to cast it as integer to sort it as 1,2,3 ...
Change your query in custom_category_id_filter as follows:
$mvs = $wpdb->get_col( " SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = 'category_id' ORDER BY CAST( meta_value AS SIGNED INTEGER ) ASC " );
Hope this helps you :-)