Woocommerce - Change Widget to include Category - php

I use woocommerce and the standard widgets are fine, but I want to add the option to show products only from a certain category. Here is the code for the standard widget:
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* List products. One widget to rule them all.
*
* #author WooThemes
* #category Widgets
* #package WooCommerce/Widgets
* #version 2.3.0
* #extends WC_Widget
*/
class WC_Widget_Products extends WC_Widget {
/**
* Constructor
*/
public function __construct() {
$this->widget_cssclass = 'woocommerce widget_products';
$this->widget_description = __( 'Display a list of your products on your site.', 'woocommerce' );
$this->widget_id = 'woocommerce_products';
$this->widget_name = __( 'WooCommerce Products', 'woocommerce' );
$this->settings = array(
'title' => array(
'type' => 'text',
'std' => __( 'Products', 'woocommerce' ),
'label' => __( 'Title', 'woocommerce' )
),
'number' => array(
'type' => 'number',
'step' => 1,
'min' => 1,
'max' => '',
'std' => 5,
'label' => __( 'Number of products to show', 'woocommerce' )
),
'show' => array(
'type' => 'select',
'std' => '',
'label' => __( 'Show', 'woocommerce' ),
'options' => array(
'' => __( 'All Products', 'woocommerce' ),
'featured' => __( 'Featured Products', 'woocommerce' ),
'onsale' => __( 'On-sale Products', 'woocommerce' ),
)
),
'orderby' => array(
'type' => 'select',
'std' => 'date',
'label' => __( 'Order by', 'woocommerce' ),
'options' => array(
'date' => __( 'Date', 'woocommerce' ),
'price' => __( 'Price', 'woocommerce' ),
'rand' => __( 'Random', 'woocommerce' ),
'sales' => __( 'Sales', 'woocommerce' ),
)
),
'order' => array(
'type' => 'select',
'std' => 'desc',
'label' => _x( 'Order', 'Sorting order', 'woocommerce' ),
'options' => array(
'asc' => __( 'ASC', 'woocommerce' ),
'desc' => __( 'DESC', 'woocommerce' ),
)
),
'in_cat' => array(
'type' => 'text',
'std' => __( 'Category Number', 'woocommerce' ),
'label' => __( 'In Category', 'woocommerce' )
),
'hide_free' => array(
'type' => 'checkbox',
'std' => 0,
'label' => __( 'Hide free products', 'woocommerce' )
),
'show_hidden' => array(
'type' => 'checkbox',
'std' => 0,
'label' => __( 'Show hidden products', 'woocommerce' )
)
);
parent::__construct();
}
/**
* Query the products and return them
* #param array $args
* #param array $instance
* #return WP_Query
*/
public function get_products( $args, $instance ) {
$number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std'];
$show = ! empty( $instance['show'] ) ? sanitize_title( $instance['show'] ) : $this->settings['show']['std'];
$orderby = ! empty( $instance['orderby'] ) ? sanitize_title( $instance['orderby'] ) : $this->settings['orderby']['std'];
$order = ! empty( $instance['order'] ) ? sanitize_title( $instance['order'] ) : $this->settings['order']['std'];
$cat = ! empty( $instance['in_cat'] ) ? sanitize_title( $instance['in_cat'] ) : $this->settings['in_cat']['std'];
$query_args = array(
'posts_per_page' => $number,
'post_status' => 'publish',
'post_type' => 'product',
'no_found_rows' => 1,
'order' => $order,
'meta_query' => array(),
'post_type=products&cat='.$cat
);
if ( empty( $instance['show_hidden'] ) ) {
$query_args['meta_query'][] = WC()->query->visibility_meta_query();
$query_args['post_parent'] = 0;
}
if ( ! empty( $instance['hide_free'] ) ) {
$query_args['meta_query'][] = array(
'key' => '_price',
'value' => 0,
'compare' => '>',
'type' => 'DECIMAL',
);
}
$query_args['meta_query'][] = WC()->query->stock_status_meta_query();
$query_args['meta_query'] = array_filter( $query_args['meta_query'] );
switch ( $show ) {
case 'featured' :
$query_args['meta_query'][] = array(
'key' => '_featured',
'value' => 'yes'
);
break;
case 'onsale' :
$product_ids_on_sale = wc_get_product_ids_on_sale();
$product_ids_on_sale[] = 0;
$query_args['post__in'] = $product_ids_on_sale;
break;
}
switch ( $orderby ) {
case 'price' :
$query_args['meta_key'] = '_price';
$query_args['orderby'] = 'meta_value_num';
break;
case 'rand' :
$query_args['orderby'] = 'rand';
break;
case 'sales' :
$query_args['meta_key'] = 'total_sales';
$query_args['orderby'] = 'meta_value_num';
break;
default :
$query_args['orderby'] = 'date';
}
return new WP_Query( apply_filters( 'woocommerce_products_widget_query_args', $query_args ) );
}
/**
* widget function.
*
* #see WP_Widget
*
* #param array $args
* #param array $instance
*/
public function widget( $args, $instance ) {
if ( $this->get_cached_widget( $args ) ) {
return;
}
ob_start();
if ( ( $products = $this->get_products( $args, $instance ) ) && $products->have_posts() ) {
$this->widget_start( $args, $instance );
echo apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' );
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template( 'content-widget-product.php', array( 'show_rating' => false ) );
}
echo apply_filters( 'woocommerce_after_widget_product_list', '</ul>' );
$this->widget_end( $args );
}
wp_reset_postdata();
echo $this->cache_widget( $args, ob_get_clean() );
}
}
As you can see I've added line 70:
'in_cat' => array(
'type' => 'text',
'std' => __( 'Category Number', 'woocommerce' ),
'label' => __( 'In Category', 'woocommerce' )
and also at Line 101:
$cat = ! empty( $instance['in_cat'] ) ? sanitize_title( $instance['in_cat'] ) : $this->settings['in_cat']['std'];
The option is available in the widget to be able to entera category ID and it saves when I click the save button.
The bit I'm struggling with is actually applying the filter, you will see i've added to Line 110:
'post_type=products&cat='.$cat
and I've also tried:
'category_name' => $cat
But I can't get the filters to work. Could anyone point me in the right direction please?
Cheers
Chris

Product category is custom taxonomy, you need to use 'tax_query' to solve the purpose as follows,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $cat,
),
),
Here, $cat should be string/array of taxonomy terms.
Even you can use, woocommerce shortcode if it suites your requirement,
[product_category category="appliances"]
Here, 'appliances' is slug of product category.

Related

White screen for wp-admin after wordpress function.php change (no log errors)

After my function.php code was modified I get a white screen when trying to go to my wordpress /wp-admin page. What could be causing the issue? Also general code improvement are welcome, as I never coded in php or wordpress before.
function.php file
<?php
function register_my_menus() {
register_nav_menus(
array(
'header-menu' => __( 'Header Menu' ),
'footer-menu1' => __( 'Footer Menu 1' ),
'footer-menu2' => __( 'Footer Menu 2' ),
'footer-menu3' => __( 'Footer Menu 3' ),
'side-menu' => __( 'Side Menu' ),
)
);
}
add_action( 'init', 'register_my_menus' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'custom-logo' );
add_filter ( 'nav_menu_css_class', 'so_37823371_menu_item_class', 10, 4 );
function so_37823371_menu_item_class ( $classes, $item, $args, $depth ){
$classes[] = 'nav-item';
return $classes;
}
add_filter( 'nav_menu_link_attributes', function($atts) {
$atts['class'] = "nav-link";
return $atts;
}, 100, 1 );
function my_theme_assets_files() {
wp_enqueue_script( 'custom-js', get_template_directory_uri(). '/js/custom.js' , [], '1.0.0' , true );
wp_localize_script( 'custom-js', 'jsh_ajax', [
'ajax_url' => admin_url( 'admin-ajax.php' )
]);
}
add_action( 'wp_enqueue_scripts', 'my_theme_assets_files' );
add_action("wp_ajax_sk_ajax_posts", "sk_ajax_posts");
add_action("wp_ajax_nopriv_sk_ajax_posts", "sk_ajax_posts");
function sk_ajax_posts() {
$cat_id = $_POST['cat_id'];
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'cat' => $cat_id ,
// 'orderby’ => 'title',
// 'order’ => 'ASC',
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
//the_post();
$categories = get_the_category();
$category_name = $categories[0]->name;
?>
<div class="col-md-4 ">
<div class="card border-0">
<div class="image-parent">
<?php echo wp_get_attachment_image( get_post_thumbnail_id( get_the_ID() ), 'full', '', [ 'class' => 'card-img-top' ] ); ?>
<?php echo $category_name; ?>
</div>
<div class="card-body">
<!-- <h6>April 25, 2022</h6> -->
<h5 class="card-title"><?php the_title(); ?></h5>
<p class="card-text"><?php the_excerpt()?></p>
Read the article
</div>
</div>
</div>
<?php
endwhile;
echo paginate_links(array(
'total' => $loop->max_num_pages,
'prev_text' => __('Previous'),
'next_text' => __('Next')
)) . "</div>";
wp_reset_postdata();
die();
}
/*
* Creating a function to create our CPT
*/
function fisher_custom_post_type_advisor() {
// Set UI labels for Custom Post Type
$labels = array(
'name' => _x( 'Advisor\'s', 'Post Type General Name', 'twentytwentyone' ),
'singular_name' => _x( 'advisor', 'Post Type Singular Name', 'twentytwentyone' ),
'menu_name' => __( 'Advisor\'s', 'twentytwentyone' ),
'parent_item_colon' => __( 'advisor', 'twentytwentyone' ),
'all_items' => __( 'All Advisor\'s', 'twentytwentyone' ),
'view_item' => __( 'View Advisor', 'twentytwentyone' ),
'add_new_item' => __( 'Add New Advisor', 'twentytwentyone' ),
'add_new' => __( 'Add New', 'twentytwentyone' ),
'edit_item' => __( 'Edit Advisor', 'twentytwentyone' ),
'update_item' => __( 'Update Advisor', 'twentytwentyone' ),
'search_items' => __( 'Search Advisor', 'twentytwentyone' ),
'not_found' => __( 'Not Found', 'twentytwentyone' ),
'not_found_in_trash' => __( 'Not found in Trash', 'twentytwentyone' ),
);
// Set other options for Custom Post Type
$args = array(
'label' => __( 'Advisor\'s', 'twentytwentyone' ),
'description' => __( 'Advisor\' news and reviews', 'twentytwentyone' ),
'labels' => $labels,
// Features this CPT supports in Post Editor
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions' ),
// You can associate this CPT with a taxonomy or custom taxonomy.
// 'taxonomies' => array( 'genres' ),
/* A hierarchical CPT is like Pages and can have
* Parent and child items. A non-hierarchical CPT
* is like Posts.
*/
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'can_export' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'advisors' ),
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => false,
);
// Registering your Custom Post Type
register_post_type( 'all-advisors', $args );
}
/* Hook into the 'init' action so that the function
* Containing our post type registration is not
* unnecessarily executed.
*/
add_action( 'init', 'fisher_custom_post_type_advisor', 0 );
function global_notice_meta_box() {
add_meta_box(
'advisor-first-name',
__( 'Advisor Detail', 'sitepoint' ),
'global_notice_meta_box_callback',
'all-advisors'
);
}
add_action( 'add_meta_boxes', 'global_notice_meta_box' );
function global_notice_meta_box_callback( $post ) {
// Add a nonce field so we can check for it later.
wp_nonce_field( 'fisher_advisor', 'fisher_advisor' );
global $fields;
$fields = [
array (
'key' => 'first_name',
'label'=> __( 'Full Name'),
'type' => 'text'
),
array (
'key' => 'role',
'label'=> __( 'Title'),
'type' => 'text'
),
array (
'key' => 'professional_certificate_short_form',
'label'=> __( 'Professional Certifications (Short)'),
'type' => 'text'
),
array (
'key' => 'professional_certificate',
'label'=> __( 'Professional Certifications'),
'type' => 'text'
),
array (
'key' => 'adress',
'label'=> __( 'Full Address'),
'type' => 'text'
),
array (
'key' => 'city',
'label' => __( 'Location'),
'type' => 'text'
),
array (
'key' => 'phone',
'label' => __( 'Phone' ),
'type' => 'tel'
),
array (
'key' => 'email',
'label' => __( 'Email' ),
'type' => 'email'
)
];
foreach ( $fields as $field ) {
$value = get_post_meta( $post->ID, '_advisor_'. $field['key'], true );
if ( $field['key'] == 'city' ) {
$args = [ 'post_type' => 'all-locations', 'posts_per_page' => -1 ];
$locations = new WP_Query($args);
if ( $locations->have_posts() ) {
echo '<label><span>' . $field['label'] .'</span>';
echo '<select name="advisor_' . $field['key'] . '">';
while ( $locations->have_posts() ) {
$locations->the_post();
echo '<option value="' . get_the_title() . '">' . get_the_title() . '</option>';
}
echo '</select></label>';
}
} else {
$value = get_post_meta( $post->ID, '_advisor_'. $field['key'], true );
echo '<label><span>' . $field['label'] .'</span> <input type="'. $field['type'] .'" name="advisor_' . $field['key'] . '" value="' . esc_attr( $value ) . '" /></label>';
echo '<br>';
}
}
}
function save_global_notice_meta_box_data( $post_id ) {
// Check if our nonce is set.
if ( ! isset( $_POST['fisher_advisor'] ) ) {
return;
}
// Verify that the nonce is valid.
if ( ! wp_verify_nonce( $_POST['fisher_advisor'], 'fisher_advisor' ) ) {
return;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check the user's permissions.
if ( isset( $_POST['post_type'] ) && 'all-advisors' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
}
else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
/* OK, it's safe for us to save the data now. */
// Make sure that it is set.
$fields = [
array (
'key' => 'first_name',
'label'=> __( 'Full Name'),
'type' => 'text'
),
array (
'key' => 'role',
'label'=> __( 'Title'),
'type' => 'text'
),
array (
'key' => 'professional_certificate_short_form',
'label'=> __( 'Professional Certifications (Short)'),
'type' => 'text'
),
array (
'key' => 'professional_certificate',
'label'=> __( 'Professional Certifications'),
'type' => 'text'
),
array (
'key' => 'adress',
'label'=> __( 'Full Address'),
'type' => 'text'
),
array (
'key' => 'city',
'label' => __( 'Location'),
'type' => 'text'
),
array (
'key' => 'phone',
'label' => __( 'Phone' ),
'type' => 'tel'
),
array (
'key' => 'email',
'label' => __( 'Email' ),
'type' => 'email'
)
];
foreach ( $fields as $field ) {
if ( ! isset( $_POST['advisor_' . $field['key']] ) ) return;
$sav_field = sanitize_text_field( $_POST['advisor_' . $field['key']] );
update_post_meta( $post_id, '_advisor_' . $field['key'], $sav_field );
}
}
add_action( 'save_post', 'save_global_notice_meta_box_data' );
/*****cpt for location ***/
/*
* Creating a function to create our CPT
*/
function fisher_custom_post_type_location() {
// Set UI labels for Custom Post Type
$labels = array(
'name' => _x( 'Location\'s', 'Post Type General Name', 'twentytwentyone' ),
'singular_name' => _x( 'Location', 'Post Type Singular Name', 'twentytwentyone' ),
'menu_name' => __( 'Location\'s', 'twentytwentyone' ),
'parent_item_colon' => __( 'Location', 'twentytwentyone' ),
'all_items' => __( 'All Location\'s', 'twentytwentyone' ),
'view_item' => __( 'View Location', 'twentytwentyone' ),
'add_new_item' => __( 'Add New Location', 'twentytwentyone' ),
'add_new' => __( 'Add New', 'twentytwentyone' ),
'edit_item' => __( 'Edit Location', 'twentytwentyone' ),
'update_item' => __( 'Update Location', 'twentytwentyone' ),
'search_items' => __( 'Search Location', 'twentytwentyone' ),
'not_found' => __( 'Not Found', 'twentytwentyone' ),
'not_found_in_trash' => __( 'Not found in Trash', 'twentytwentyone' ),
);
// Set other options for Custom Post Type
$args = array(
'label' => __( 'Location\'s', 'twentytwentyone' ),
'description' => __( 'Location\' news and reviews', 'twentytwentyone' ),
'labels' => $labels,
// Features this CPT supports in Post Editor
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions' ),
// You can associate this CPT with a taxonomy or custom taxonomy.
// 'taxonomies' => array( 'genres' ),
/* A hierarchical CPT is like Pages and can have
* Parent and child items. A non-hierarchical CPT
* is like Posts.
*/
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'can_export' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'locations' ),
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => false,
);
// Registering your Custom Post Type
register_post_type( 'all-locations', $args );
}
/* Hook into the 'init' action so that the function
* Containing our post type registration is not
* unnecessarily executed.
*/
add_action( 'init', 'fisher_custom_post_type_location', 0 );
/****locatin-meta-box**** */
function global_notice_meta_box_location() {
add_meta_box(
'advisor-first-name',
__( 'Location Detail', 'sitepoint' ),
'global_notice_meta_box_location_callback',
'all-locations'
);
}
add_action( 'add_meta_boxes', 'global_notice_meta_box_location' );
function global_notice_meta_box_location_callback( $post ) {
// Add a nonce field so we can check for it later.
wp_nonce_field( 'fisher_location', 'fisher_location' );
global $fields;
$fields = [
array (
'key' => 'city',
'label'=> __( 'city'),
'type' => 'text'
),
array (
'key' => 'adress',
'label'=> __( 'adress'),
'type' => 'text'
),
array (
'key' => 'phone',
'label' => __( 'Phone' ),
'type' => 'tel'
),
array (
'key' => 'lati',
'label' => __( 'latitutde' ),
'type' => 'text'
),
array (
'key' => 'langi',
'label' => __( 'langitude' ),
'type' => 'text'
),
];
foreach ( $fields as $field ) {
$value = get_post_meta( $post->ID, '_location_'. $field['key'], true );
echo '<label><span>' . $field['label'] .'</span> <input type="'. $field['type'] .'" name="location_' . $field['key'] . '" value="' . esc_attr( $value ) . '" /></label>';
echo '<br>';
}
}
function save_global_notice_meta_box_location_data( $post_id ) {
// Check if our nonce is set.
if ( ! isset( $_POST['fisher_location'] ) ) {
return;
}
// Verify that the nonce is valid.
if ( ! wp_verify_nonce( $_POST['fisher_location'], 'fisher_location' ) ) {
return;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check the user's permissions.
if ( isset( $_POST['post_type'] ) && 'all-locations' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
}
else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
/* OK, it's safe for us to save the data now. */
// Make sure that it is set.
$fields = [
array (
'key' => 'city',
'label'=> __( 'city'),
'type' => 'text'
),
array (
'key' => 'adress',
'label'=> __( 'adress'),
'type' => 'text'
),
array (
'key' => 'phone',
'label' => __( 'Phone' ),
'type' => 'tel'
),
array (
'key' => 'lati',
'label' => __( 'latitutde' ),
'type' => 'text'
),
array (
'key' => 'langi',
'label' => __( 'langitude' ),
'type' => 'text'
),
];
foreach ( $fields as $field ) {
if ( ! isset( $_POST['location_' . $field['key']] ) ) return;
$sav_field = sanitize_text_field( $_POST['location_' . $field['key']] );
update_post_meta( $post_id, '_location_' . $field['key'], $sav_field );
}
}
When the below was added, I started getting a blank screen for wordpress when I go to /wp-admin
add_action( 'save_post', 'save_global_notice_meta_box_location_data' );
?>
<?php
//SETTING UP THE PAGE
function set_page() {
add_menu_page('Social Media Links', 'Social Media Links', 'manage_options', 'theme_settings', 'the_page', 'dashicons-share', 40);
}
//CALLING THE FUNCTION
add_action('admin_menu', 'set_page');?>
<?php //THE PAGE
function the_page() {?>
<link rel="stylesheet" href="<?php echo get_template_directory_uri()?>/css/bootstrap.min.css">
<legend style="background: #2271b1;color: #fff;padding: 15px 30px;margin-bottom: 60px;margin-top: 10px;padding-right: 85px;max-width: 99%;">Social media linked accounts</legend>
<div class="container"><div class="row"><div class="col-md-12">
<form method="post" action="options.php">
<?php settings_fields('theme_settings'); ?>
<?php $options = get_option('theme_settings'); ?>
<?php if ($_REQUEST['settings-updated']) : ?>
<div class="updated">
<p><strong class="alret">
<?php _e('Options saved'); ?>
</strong></p>
</div>
<?php endif; ?>
<div class="the-container">
<div id="social" class="container tab-pane fade active show"><br>
<fieldset>
<?php $social_arr = ['facebook','twitter','linkedin','youtube'];
foreach($social_arr as $social){?>
<div class="form-group form_builder_row facebook_container row">
<div class="col-md-2 form_builder_col">
<label class="control-label <?php echo $social;?>" for="<?php echo $social;?>">
<?php echo ucfirst($social);?>:</label>
</div>
<div class="col-md-6 form_builder_col">
<input type="text" class=" form_builder_field form-control input-text field_<?php echo $social;?>" id="<?php echo $social;?>" name="theme_settings[<?php echo $social;?>]" value="<?php echo $options[$social];?>" placeholder="<?php echo ucfirst($social);?>">
</div></div>
<?php }?>
</fieldset>
</div>
</div>
<p class="mt-4">
<input name="theme_settings[submit]" id="submit" value="Save Changes" type="submit" class="button button-primary btn-md ml-3">
</p>
</form>
</div></div></div>
<?php } ?>
<?php
//REGISTERING SETTINGS AND FIELDS
function register_settings_and_fields() {
register_setting('theme_settings','theme_settings');
}
add_action('admin_init', 'register_settings_and_fields');
?>
Have you opened wp-config.php? and set WP_DEBUG to true; this can show some errors more intuitively
Don't use function names like this the_page set_page use a prefix before function name e.g.: lefty_wp_set_page , lefty_wp_the_page or give a function a meaningful name, don't just copy paste things from internet, do some modifications in it to avoid conflicts.

Problem with foreach array on select option on woocmmerce function class

I create a function to add different shiping prices foreach user, all works fine for only one user (the first on the list), but i can't get to make the select options foreach user, it only shows 1 option with all the user in it.
the problem is integrate the foreach in here: 'test' => array. It creates the html elemnt but only 1 and not 1 foreach user
my code:
class WC_Shipping_click extends WC_Shipping_Method {
public function __construct( $instance_id = 0 ) {
$args = array(
'role' => '',
'orderby' => 'user_nicename',
'order' => 'ASC'
);
$users = get_users( $args );
foreach ( $users as $user ){
$userinfo .= '['.$user->precio.','.$user->first_name.'] ';
}
$this->id = 'click_method';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Click Shipping Method' );
$this->method_description = __( 'Click Shipping' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->instance_form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable' ),
'type' => 'checkbox',
'label' => __( 'Enable this shipping method' ),
'default' => 'yes',
),
'test' => array(
'title' => __( 'Prueba de array' ),
'description' => $user->first_name,
'type' => 'select',
'options' => array( ''.$userinfo.'' => ''.$userinfo'',),
'label' => __( 'Some field' ),
'required' => true,
)
)
);
$this->enabled = $this->get_option( 'enabled' );
$this->prueba = $this->get_option( 'prueba' );
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* #param array $package (default: array())
*/
public function calculate_shipping( $package = array() ) {
$this->add_rate( array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => $this->test,
) );
}
}
This is the scope of your foreach()
foreach ( $users as $user ){
$userinfo .= '['.$user->precio.','.$user->first_name.'] ';
}
Nothing that is below will fall into this foreach() loop.

Wordpress Job Manager search-hero widget button redirect

I am modifying a wordpress theme 'jobify' . In their demo they have a 'search hero' widget with a button which takes you to a jobs listings page. Inspecting in chrome:
<form class="job_search_form job_search_form--flat"
action="https://jobify-demos.astoundify.com/classic/find-a-job/"
method="GET">
Their 'find-a-job' page which you get taken to with the button has google maps which I don't want. So I have created a new [jobs] page I named 'job-search' without the map. If I edit the above url to that in chrome inspector then the button outputs the search results correctly on my new page. following this
I have now spent 2 days going through all the widget php code trying to find where I change that GET command url on this widget button from 'find-a-job' to 'job-search'. Adjusting this on a newly made search page seems straightforward as seen on this SO question
I have read about customising their widgets here and thought it would be in the class-widget-search-hero.php file (below). I have also checked its scss file but don't see anything there. So many hours looking, is it something as simple as deleting one of the two [jobs] pages? Thank you.
<?php
/**
* Home: Search Hero
*
* #package Jobify
* #category Widget
* #since 3.0.0
*/
class Jobify_Widget_Search_Hero extends Jobify_Widget {
public function __construct() {
$this->widget_description = __( 'Display a "hero" search area.', 'jobify' );
$this->widget_id = 'jobify_widget_search_hero';
$this->widget_cssclass = 'widget--home-hero-search';
$this->widget_name = __( 'Jobify - Page: Search Hero', 'jobify' );
$this->control_ops = array(
'width' => 400,
);
$this->settings = array(
'home widgetized' => array(
'std' => __( 'Homepage/Widgetized', 'jobify' ),
'type' => 'widget-area',
),
'height' => array(
'type' => 'select',
'std' => 'medium',
'label' => __( 'Hero Height', 'jobify' ),
'options' => array(
'small' => __( 'Small', 'jobify' ),
'medium' => __( 'Medium', 'jobify' ),
'large' => __( 'Large', 'jobify' ),
),
),
'margin' => array(
'type' => 'checkbox',
'std' => 1,
'label' => __( 'Add standard spacing above/below widget', 'jobify' ),
),
'text_color' => array(
'type' => 'colorpicker',
'std' => '#ffffff',
'label' => __( 'Text Color:', 'jobify' ),
),
'title' => array(
'type' => 'text',
'std' => '',
'label' => __( 'Title:', 'jobify' ),
),
'description' => array(
'type' => 'text',
'std' => '',
'label' => __( 'Description:', 'jobify' ),
'rows' => 5,
),
'image' => array(
'type' => 'image',
'std' => '',
'label' => __( 'Background Image:', 'jobify' ),
),
'background_position' => array(
'type' => 'select',
'std' => 'center center',
'label' => __( 'Image Position:', 'jobify' ),
'options' => array(
'left top' => __( 'Left Top', 'jobify' ),
'left center' => __( 'Left Center', 'jobify' ),
'left bottom' => __( 'Left Bottom', 'jobify' ),
'right top' => __( 'Right Top', 'jobify' ),
'right center' => __( 'Right Center', 'jobify' ),
'right bottom' => __( 'Right Bottom', 'jobify' ),
'center top' => __( 'Center Top', 'jobify' ),
'center center' => __( 'Center Center', 'jobify' ),
'center bottom' => __( 'Center Bottom', 'jobify' ),
'center top' => __( 'Center Top', 'jobify' ),
),
),
'cover_overlay' => array(
'type' => 'checkbox',
'std' => 1,
'label' => __( 'Use transparent overlay', 'jobify' ),
),
);
if ( jobify()->get( 'wp-job-manager-resumes' ) ) {
$what = array(
'what' => array(
'type' => 'select',
'std' => 'job',
'label' => __( 'Search:', 'jobify' ),
'options' => array(
'job' => __( 'Jobs', 'jobify' ),
'resume' => __( 'Resumes', 'jobify' ),
),
),
);
$this->settings = $what + $this->settings;
}
parent::__construct();
}
function widget( $args, $instance ) {
extract( $args );
$text_align = isset( $instance['text_align'] ) ? esc_attr( $instance['text_align'] ) : 'left';
$background_position = isset( $instance['background_position'] ) ? esc_attr( $instance['background_position'] ) : 'center center';
$overlay = isset( $instance['cover_overlay'] ) && 1 == $instance['cover_overlay'] ? 'has-overlay' : 'no-overlay';
$margin = isset( $instance['margin'] ) && 1 == $instance['margin'] ? true : false;
$height = isset( $instance['height'] ) ? esc_attr( $instance['height'] ) : 'medium';
if ( ! $margin ) {
$before_widget = str_replace( 'widget--home ', 'widget--home widget--home--no-margin ', $before_widget );
}
$image = isset( $instance['image'] ) ? esc_url( $instance['image'] ) : null;
$content = $this->assemble_content( $instance );
$what = isset( $instance['what'] ) ? esc_attr( $instance['what'] ) : 'job';
global $is_flat;
$is_flat = true;
ob_start();
?>
<?php echo $before_widget; ?>
<div class="hero-search hero-search--<?php echo esc_attr( $overlay ); ?> hero-search--height-<?php echo esc_attr( $height ); ?>" style="background-image:url(<?php echo $image; ?>); ?>; background-position: <?php echo $background_position; ?>">
<div class="container">
<?php echo $content; ?>
<?php locate_template( array( $what . '-filters-flat.php' ), true, false ); ?>
</div>
</div>
<?php echo $after_widget; ?>
<?php
$content = ob_get_clean();
echo apply_filters( $this->widget_id, $content );
}
private function assemble_content( $instance ) {
$text_color = isset( $instance['text_color'] ) ? esc_attr( $instance['text_color'] ) : '#fff';
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
$content = isset( $instance['description'] ) ? $instance['description'] : '';
$output = '<div class="hero-search__content" style="color:' . $text_color . '">';
$output .= '<h2 class="hero-search__title" style="color:' . $text_color . '">' . $title . '</h2>';
$output .= wpautop( $content );
$output .= '</div>';
return $output;
}
}
The solution (if not technical answer) was actually very easy once found.
After reading this tutorial and seeing the line:
$action_page_id = get_option('job_manager_jobs_page_id');
Then searching "job_manager_jobs_page_id" and finding this on github I discovered it exists under the job manager settings /wp-admin/edit.php?post_type=job_listing&page=job-manager-settings#settings-job_pages where you just change the 'Job Listings' page in the drop down from 'find a job' to my new 'job search' page. All working.

Creating a Wordpress Widget from another theme

I'm trying to add the job search functionality found at the top of this website: https://jobify-demos.astoundify.com/classic/ to my own WP theme I am building.
I've identified that this 'Search Hero Strip' is a widget which needs installing into my theme and then I guess I need to create a widetized area in my own theme so I can add this.
I believe this is the widget from the theme:
<?php
/**
* Home: Search Hero
*
* #package Jobify
* #category Widget
* #since 3.0.0
*/
class Jobify_Widget_Search_Hero extends Jobify_Widget {
public function __construct() {
$this->widget_description = __( 'Display a "hero" search area.', 'jobify' );
$this->widget_id = 'jobify_widget_search_hero';
$this->widget_cssclass = 'widget--home-hero-search';
$this->widget_name = __( 'Jobify - Page: Search Hero', 'jobify' );
$this->control_ops = array(
'width' => 400
);
$this->settings = array(
'home widgetized' => array(
'std' => __( 'Homepage/Widgetized', 'jobify' ),
'type' => 'widget-area'
),
'height' => array(
'type' => 'select',
'std' => 'medium',
'label' => __( 'Hero Height', 'jobify' ),
'options' => array(
'small' => __( 'Small', 'jobify' ),
'medium' => __( 'Medium', 'jobify' ),
'large' => __( 'Large', 'jobify' )
)
),
'margin' => array(
'type' => 'checkbox',
'std' => 1,
'label' => __( 'Add standard spacing above/below widget', 'jobify' )
),
'text_color' => array(
'type' => 'colorpicker',
'std' => '#ffffff',
'label' => __( 'Text Color:', 'jobify' )
),
'title' => array(
'type' => 'text',
'std' => '',
'label' => __( 'Title:', 'jobify' )
),
'description' => array(
'type' => 'text',
'std' => '',
'label' => __( 'Description:', 'jobify' ),
'rows' => 5
),
'image' => array(
'type' => 'image',
'std' => '',
'label' => __( 'Background Image:', 'jobify' )
),
'background_position' => array(
'type' => 'select',
'std' => 'center center',
'label' => __( 'Image Position:', 'jobify' ),
'options' => array(
'left top' => __( 'Left Top', 'jobify' ),
'left center' => __( 'Left Center', 'jobify' ),
'left bottom' => __( 'Left Bottom', 'jobify' ),
'right top' => __( 'Right Top', 'jobify' ),
'right center' => __( 'Right Center', 'jobify' ),
'right bottom' => __( 'Right Bottom', 'jobify' ),
'center top' => __( 'Center Top', 'jobify' ),
'center center' => __( 'Center Center', 'jobify' ),
'center bottom' => __( 'Center Bottom', 'jobify' ),
'center top' => __( 'Center Top', 'jobify' )
)
),
'cover_overlay' => array(
'type' => 'checkbox',
'std' => 1,
'label' => __( 'Use transparent overlay', 'jobify' )
),
);
if ( jobify()->get( 'wp-job-manager-resumes' ) ) {
$what = array(
'what' => array(
'type' => 'select',
'std' => 'job',
'label' => __( 'Search:', 'jobify' ),
'options' => array(
'job' => __( 'Jobs', 'jobify' ),
'resume' => __( 'Resumes', 'jobify' )
)
)
);
$this->settings = $what + $this->settings;
}
parent::__construct();
}
function widget( $args, $instance ) {
extract( $args );
$text_align = isset( $instance[ 'text_align' ] ) ? esc_attr( $instance[ 'text_align' ] ) : 'left';
$background_position = isset( $instance[ 'background_position' ] ) ? esc_attr( $instance[ 'background_position' ] ) : 'center center';
$overlay = isset( $instance[ 'cover_overlay' ] ) && 1 == $instance[ 'cover_overlay' ] ? 'has-overlay' : 'no-overlay';
$margin = isset( $instance[ 'margin' ] ) && 1 == $instance[ 'margin' ] ? true : false;
$height = isset( $instance[ 'height' ] ) ? esc_attr( $instance[ 'height' ] ) : 'medium';
if ( ! $margin ) {
$before_widget = str_replace( 'widget--home ', 'widget--home widget--home--no-margin ', $before_widget );
}
$image = isset( $instance[ 'image' ] ) ? esc_url( $instance[ 'image' ] ) : null;
$content = $this->assemble_content( $instance );
$what = isset( $instance[ 'what' ] ) ? esc_attr( $instance[ 'what' ] ) : 'job';
global $is_flat;
$is_flat = true;
ob_start();
?>
<?php echo $before_widget; ?>
<div class="hero-search hero-search--<?php echo esc_attr( $overlay ); ?> hero-search--height-<?php echo esc_attr( $height ); ?>" style="background-image:url(<?php echo $image; ?>); ?>; background-position: <?php echo $background_position; ?>">
<div class="container">
<?php echo $content; ?>
<?php locate_template( array( $what . '-filters-flat.php' ), true, false ); ?>
</div>
</div>
<?php echo $after_widget; ?>
<?php
$content = ob_get_clean();
echo apply_filters( $this->widget_id, $content );
}
private function assemble_content( $instance ) {
$text_color = isset( $instance[ 'text_color' ] ) ? esc_attr( $instance[ 'text_color' ] ) : '#fff';
$title = isset( $instance[ 'title' ] ) ? esc_attr( $instance[ 'title' ] ) : '';
$content = isset( $instance[ 'description' ] ) ? $instance[ 'description' ] : '';
$output = '<div class="hero-search__content" style="color:' . $text_color . '">';
$output .= '<h2 class="hero-search__title" style="color:' . $text_color . '">' . $title . '</h2>';
$output .= wpautop( $content );
$output .= '</div>';
return $output;
}
}
I've tried to add this inside the functions file but it just produces errors.
I know this might come across as basic and im sure im missing somehting important, but im a bit stuck.
I'd either want to do it as a widget or strip out the search form from it and just add it to my home template page - is either possibe?

WooCommerce Conditional Custom Fields if Product Category in Cart

OK, I'm stumped. I've searched and read several posts including the related post Checking products in cart based on category name woocommerce? from where I derived much of this code, and Woocommerce - Add filter to display (or hide) custom checkout field if product ID == # which is specific to Product IDs, not Category IDs.
I want to display the sdc_custom_checkout_field if, and only if, the target category ID (237 in this case) is in the cart.
I tried commenting out the sdc_custom_checkout_field function and using a simple test shown below, but kept getting "Nope!", so I assume the query is incorrect.
add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );
function sdc_custom_checkout_field( $checkout ) {
//Check if Product in Cart
//$product_in_cart = check_product_in_cart();
//Product is in cart so show additional fields
if ( $product_in_cart === true ) {
echo '<div id="my_custom_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');
woocommerce_form_field( 'dupecard_location', array(
'type' => 'text',
'class' => array( 'dupecard-location form-row-wide' ),
'label' => __( 'Course Location' ),
), $checkout->get_value( 'dupecard_location' ) );
woocommerce_form_field( 'dupecard_instructor', array(
'type' => 'text',
'class' => array( 'dupecard-instructor form-row-wide' ),
'label' => __( 'Instructor Name' ),
), $checkout->get_value( 'dupecard_instructor' ) );
woocommerce_form_field( 'dupecard_requestor_name', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-name form-row-wide' ),
'label' => __( 'Requestor Name' ),
), $checkout->get_value( 'dupecard_requestor_name' ) );
woocommerce_form_field( 'dupecard_requestor_email', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-email form-row-wide' ),
'label' => __( 'Requestor Email' ),
), $checkout->get_value( 'dupecard_requestor_email' ) );
woocommerce_form_field( 'dupecard_requestor_phone', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-phone form-row-wide' ),
'label' => __( 'Requestor Phone' ),
), $checkout->get_value( 'dupecard_requestor_phone' ) );
echo '</div>';
}
}
function check_product_in_cart() {
//Check to see if user has product in cart
global $woocommerce;
//assign default negative value
$product_in_cart = false;
// start cart items fetch loop
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
$terms = get_the_terms( $_product->id, 'product_cat' );
// second level loop search, in case some items have several categories
$cat_ids = array();
foreach ($terms as $term) {
$cat_ids[] = $term->term_id;
}
if(in_array(237, (array)$cat_ids)) {
//category is in cart!
$product_in_cart = true;
}
}
return $product_in_cart;
}
Here’s the test snippet:
if ($item_in_cart === true) {echo 'YES';}
else {echo 'Nope!';}
I also replaced
$item_in_cart
with
$product_in_cart
but it made no difference.
********** EDIT RESPONSE TO #PRAFULLA **********
#Prafulla - thanks for your input. I appreciate it. I modified my snippet as follows, incorporating yours, but was unable to get it to work. I'm a PHP newbie, so, no surprise. Do you have additional advice?
add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );
function sdc_custom_checkout_field( $checkout ) {
//Check if Product in Cart
$your_product_category = is_category_in_cart();
//Product is in cart so show additional fields
if ( $your_product_category === true ) {
echo '<div id="my_custom_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');
woocommerce_form_field( 'dupecard_location', array(
'type' => 'text',
'class' => array( 'dupecard-location form-row-wide' ),
'label' => __( 'Course Location' ),
), $checkout->get_value( 'dupecard_location' ) );
woocommerce_form_field( 'dupecard_instructor', array(
'type' => 'text',
'class' => array( 'dupecard-instructor form-row-wide' ),
'label' => __( 'Instructor Name' ),
), $checkout->get_value( 'dupecard_instructor' ) );
woocommerce_form_field( 'dupecard_requestor_name', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-name form-row-wide' ),
'label' => __( 'Requestor Name' ),
), $checkout->get_value( 'dupecard_requestor_name' ) );
woocommerce_form_field( 'dupecard_requestor_email', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-email form-row-wide' ),
'label' => __( 'Requestor Email' ),
), $checkout->get_value( 'dupecard_requestor_email' ) );
woocommerce_form_field( 'dupecard_requestor_phone', array(
'type' => 'text',
'class' => array( 'dupecard-requestor-phone form-row-wide' ),
'label' => __( 'Requestor Phone' ),
), $checkout->get_value( 'dupecard_requestor_phone' ) );
echo '</div>';
}
}
function is_category_in_cart( $your_product_category = 237 ){
global $woocommerce;
$products_in_cart = $woocommerce->cart->get_cart();
$product_types_in_cart = array_column( $products_in_cart, 'data' );
//if ( $product_types_in_cart[0]->product_type == 'subscription' ) { this is what I have tested
if ( $product_types_in_cart[0]->product_cat == $your_product_category ) {
return true;
}
return $your_product_category;
}
After much work, research, and the assistance of some paid help on another website, this is the working result:
// Add the field to the checkout
add_action( 'woocommerce_before_order_notes', 'sdc_custom_checkout_field' );
function sdc_custom_checkout_field( $checkout ) {
if( check_product_category() ){
echo '<div id="sdc_checkout_field"><h3>' . __( 'Duplicate Card Information' . '</h3><br>');
woocommerce_form_field( 'dupecard_location', array(
'type' => 'text',
'required' => true,
'class' => array( 'dupecard-location form-row-wide' ),
'label' => __( 'Course Location' ),
), $checkout->get_value( 'dupecard_location' ) );
woocommerce_form_field( 'dupecard_instructor', array(
'type' => 'text',
'required' => true,
'class' => array( 'dupecard-instructor form-row-wide' ),
'label' => __( 'Instructor Name' ),
), $checkout->get_value( 'dupecard_instructor' ) );
woocommerce_form_field( 'dupecard_requestor_name', array(
'type' => 'text',
'required' => true,
'class' => array( 'dupecard-requestor-name form-row-wide' ),
'label' => __( 'Requestor Name' ),
), $checkout->get_value( 'dupecard_requestor_name' ) );
woocommerce_form_field( 'dupecard_requestor_email', array(
'type' => 'text',
'required' => true,
'class' => array( 'dupecard-requestor-email form-row-wide' ),
'label' => __( 'Requestor Email' ),
), $checkout->get_value( 'dupecard_requestor_email' ) );
woocommerce_form_field( 'dupecard_requestor_phone', array(
'type' => 'text',
'required' => true,
'class' => array( 'dupecard-requestor-phone form-row-wide' ),
'label' => __( 'Requestor Phone' ),
), $checkout->get_value( 'dupecard_requestor_phone' ) );
echo '</div>';
}
}
function check_product_category(){
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if( is_category_in_cart( $product_id ) ){
return true;
}
}
return false;
}
function is_category_in_cart( $product_id ){
return has_term( 237,'product_cat', get_post( $product_id ) );
}
/*Save to DB as post meta*/
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 ( ! empty( $_POST['dupecard_location'] ) ) {
update_post_meta( $order_id, 'dupecard_location', sanitize_text_field( $_POST['dupecard_location'] ) );
}
if ( ! empty( $_POST['dupecard_instructor'] ) ) {
update_post_meta( $order_id, 'dupecard_instructor', sanitize_text_field( $_POST['dupecard_instructor'] ) );
}
if ( ! empty( $_POST['dupecard_requestor_name'] ) ) {
update_post_meta( $order_id, 'dupecard_requestor_name', sanitize_text_field( $_POST['dupecard_requestor_name'] ) );
}
if ( ! empty( $_POST['dupecard_requestor_email'] ) ) {
update_post_meta( $order_id, 'dupecard_requestor_email', sanitize_text_field( $_POST['dupecard_requestor_email'] ) );
}
if ( ! empty( $_POST['dupecard_requestor_phone'] ) ) {
update_post_meta( $order_id, 'dupecard_requestor_phone', sanitize_text_field( $_POST['dupecard_requestor_phone'] ) );
}
}
This is how I get the job done in my case , please try it and note where you need to give your input on this code as It is not written for direct use.
function is_category_in_cart( $your_product_category = null ){
global $woocommerce;
$products_in_cart = $woocommerce->cart->get_cart();
$product_types_in_cart = array_column( $products_in_cart, 'data' );
//if ( $product_types_in_cart[0]->product_type == 'subscription' ) { this is what I have tested
if ( $product_types_in_cart[0]->product_cat == $your_product_category ) {
return true;
}
}

Categories