Related
I want to have dynamic options for my checkout dropdown field. The options must be users of specific roles that are in WordPress users. How can I achieve it? Below is the code that I am working with. In the first function, we can get all administrator users. I want users to be in options of the dropdown in the select field of checkout.
**User Roles**
function get_users_by_role($role, $orderby, $order) {
$args = array(
'role' => 'administrator',
'orderby' => 'user_nicename',
'order' => 'ASC'
);
$users = get_users( $args );
return $users;
}
**Dropdown Field**
function everest_custom_dropdown_fields( $fields ) {
$fields['everestmerchant_extra_dropdown_fields']['dropdown'] = array(
'label' => __('Leader Name', 'woocommerce'),
'placeholder' => _x('Leader Name', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array( 'wps-drop' ),
'clear' => true,
'type' => 'select',
'options' => array(
'option 1' => __('option 1', 'woocommerce' ),
'option 2' => __('option 2', 'woocommerce'
)//end of options
);
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'everest_custom_dropdown_fields' );
Get All Leaders
function get_leaders($role) {
$args = array(
'role' => $role,
'orderby' => 'user_nicename',
'order' => 'ASC'
);
$leaders = ['' => 'Please Select'];
$users = get_users( $args );
if($users){
foreach($users as $user){
$leaders[$user->data->ID] = $user->data->display_name;
}
}
return $leaders;
}
Add Leader field in checkout page
function leader_name_select_field( $checkout ){
woocommerce_form_field( 'leader_name', array(
'type' => 'select',
'required' => true,
'class' => array('form-row-wide'),
'label' => 'Leader Name',
'options' => get_leaders('administrator')
), $checkout->get_value( 'leader_name' ) );
}
add_action( 'woocommerce_after_checkout_billing_form', 'leader_name_select_field' );
Save Selected field in database.
function save_leader_name_of_order( $order_id ){
if( !empty( $_POST['leader_name'] ) )
update_post_meta( $order_id, 'leader_name', sanitize_text_field( $_POST['leader_name'] ) );
}
add_action( 'woocommerce_checkout_update_order_meta', 'save_leader_name_of_order' );
Show saved field in order page in dashboard
function leader_name_show_on_order_detail_page($order){
$leader_id = get_post_meta($order->get_id(), 'leader_name', true );
$leader = get_user_by( 'ID', $leader_id );
if($leader_id && $leader){
echo '<p class="form-field form-field-wide">';
echo '<label>Leader Name</label>';
echo '<p> ' . $leader->data->display_name . '</p>';
echo '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_order_details', 'leader_name_show_on_order_detail_page', 10, 1 );
I have created custom taxonomy "Brands" and attached to woocommerce products. Unfortunately, It is not available in woocommerce REST API response.
How to attach custom taxonomy term to woocommerce rest API. Currently there is no documentation about attachment of custom taxonomy. Is there any hook or filter ?
I solved by using this code.You will be able to GET and Update custom taxonomy by using this method. Basically. You can add this code in functions.php file or in plugin.
Step:1
Replace brands with your taxonomy_name.
Step:2
If your taxonomy have custom fields, replace custom_field_name with yours.
Taxonomy Code:
add_action( 'init', 'create_brands_hierarchical_taxonomy', 0 );
//create a custom taxonomy name it topics for your posts
function create_brands_hierarchical_taxonomy() {
// Add new taxonomy, make it hierarchical like categories
//first do the translations part for GUI
$labels = array(
'name' => _x( 'Brands', 'taxonomy general name' ),
'singular_name' => _x( 'Brand', 'taxonomy singular name' ),
'search_items' => __( 'Search Brands' ),
'all_items' => __( 'All Brands' ),
'parent_item' => __( 'Parent Brand' ),
'parent_item_colon' => __( 'Parent Brand:' ),
'edit_item' => __( 'Edit Brand' ),
'update_item' => __( 'Update Brand' ),
'add_new_item' => __( 'Add New Brand' ),
'new_item_name' => __( 'New Brand Name' ),
'menu_name' => __( 'Brands' ),
);
$capabilities = array(
'manage_terms' => 'manage_woocommerce',
'edit_terms' => 'manage_woocommerce',
'delete_terms' => 'manage_woocommerce',
'assign_terms' => 'manage_woocommerce',
);
// Now register the taxonomy
$args = array(
'labels' => $labels,
'show_in_rest' => true,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => false,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'capabilities' => $capabilities,
);
register_taxonomy( 'brands', array( 'product' ), $args );
register_taxonomy_for_object_type( 'brands', 'product' );
}
Register Taxonomy API for WC
//Register taxonomy API for WC
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands' );
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "brands", array(
'get_callback' => 'product_get_callback',
'update_callback' => 'product_update_callback',
'schema' => null,
));
}
//Get Taxonomy record in wc REST API
function product_get_callback($post, $attr, $request, $object_type)
{
$terms = array();
// Get terms
foreach (wp_get_post_terms( $post[ 'id' ],'brands') as $term) {
$terms[] = array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
'custom_field_name' => get_term_meta($term->term_id, 'custom_field_name', true)
);
}
return $terms;
}
//Update Taxonomy record in wc REST API
function product_update_callback($values, $post, $attr, $request, $object_type)
{
// Post ID
$postId = $post->get_id();
//Example: $values = [2,4,3];
// Set terms
wp_set_object_terms( $postId, $values , 'brands');
}
Solution above is working but you have to change the
$postId = $post->get_id();
with
$postId = $post->ID;
Took me ages to find out why update_callback did not work : $values contains the taxonomy-structure and is therefore too complex to pass as integer to wp_set_object_terms. You have to strip it to the numeric ID's only otherwise [null] is assigned
//Update Taxonomy record in wc REST API
function product_update_callback_Leerjaar($values, $post, $attr, $request, $object_type)
{
// Post ID
$postId = $post->id;
//Example: $values = [2,4,3];
error_log("debug on values");
error_log(json_encode($values));
$numarray = [];
foreach($values as $value){
$numarray[] = (int)$value['id'];
}
wp_set_object_terms( $postId, $numarray , 'brands');
}
If anyone has tested all the above and can't get it to work, I found a simplest and working solution, based on Taha Farooqui's answer and the wordpress register_rest_field documentation :
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands');
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "field_rest_name",
array("get_callback" => function ($post) {
$taxonomy = wp_get_post_terms( $post['id'], 'your_taxonomy_name');
return $taxonomy;
}
)
);
}
After months of testing trying to prove why the product_update_callback() function returned a null value, he got a version that loads the taxonomy values from the woocommerce Rest Api v3 only with the name and slug..
<?php
//Prevent a malicious user from executing php code from the browser bar
defined('ABSPATH') or die( "Bye bye" );
add_action( 'init', 'create_brands_hierarchical_taxonomy', 0 );
//create a custom taxonomy name it topics for your posts
function create_brands_hierarchical_taxonomy() {
// Add new taxonomy, make it hierarchical like categories
$labels = array(
'name' => _x( 'Marcas', 'taxonomy general name' ),
'singular_name' => _x( 'Marca', 'taxonomy singular name' ),
'search_items' => __( 'Buscar Marcas' ),
'all_items' => __( 'Todas las Marcas' ),
'parent_item' => __( 'Marca Relacionada' ),
'parent_item_colon' => __( 'Marca Relacionada:' ),
'edit_item' => __( 'Editar Marca' ),
'update_item' => __( 'Subir Marca' ),
'add_new_item' => __( 'Añadir Nueva Marca' ),
'new_item_name' => __( 'Nuevo Nombre de Marca' ),
'menu_name' => __( 'Marcas' ),
);
$capabilities = array(
'manage_terms' => 'manage_woocommerce',
'edit_terms' => 'manage_woocommerce',
'delete_terms' => 'manage_woocommerce',
'assign_terms' => 'manage_woocommerce',
);
// Now register the taxonomy
$args = array(
'labels' => $labels,
'show_in_rest' => true,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => false,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'capabilities' => $capabilities,
);
register_taxonomy( 'pwb-brand', array( 'product' ), $args );
register_taxonomy_for_object_type( 'pwb-brand', 'product' );
}
//Register taxonomy API for WC
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_brands' );
function register_rest_field_for_custom_taxonomy_brands() {
register_rest_field('product', "pwb-brand", array(
'get_callback' => 'product_get_callback_brand',
'update_callback' => 'product_update_callback_brand',
'schema' => null,
));
}
//Get Taxonomy record in wc REST API
function product_get_callback_brand($post, $attr, $request, $object_type){
$terms = array();
// Get terms
foreach (wp_get_post_terms( $post[ 'id' ],'pwb-brand') as $term) {
$terms[] = array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
);
}
return $terms;
}
//Update Taxonomy record in wc REST API
function product_update_callback_brand($values, $post, $attr, $request, $object_type){
// Post ID
$postId = $post->id;
$terms = $values;
$termName = $terms[0]['name'];
$termSlug = $terms[0]['slug'];
wp_insert_term( $termName, 'pwb-brand', array( 'slug' => $termSlug ) );
error_log("debug on values");
error_log(json_encode($values));
$newTermId = get_term_by('slug',$termSlug,'pwb-brand')->term_id;
array_push($values, array('id' => (int)$newTermId));
$numarray = [];
foreach($values as $value){
if(is_numeric($value['id'])){
$numarray[] = (int)$value['id'];
}
}
wp_set_object_terms( $postId, $numarray , 'pwb-brand');
}
After so much testing he understood that the values that pass through the product_get_callback_brand function are mandatory to register a taxonomy so if you add a custom field like in the first example then they must be loaded so that the taxonomy can be retrieved.
It is worth noting that it is not a valid field for image fields or galleries that will not have the permissions to be loaded by the Rest Api v3 of woocommerce
A have a lot of posts with custom post types in the database. In the same time the theme created the taxonomy institution:
function my_taxonomies_institutions() {
$labels = array(
'name' => _x( 'Category', 'taxonomy general name' ),
'singular_name' => _x( 'Category', 'taxonomy singular name' ),
// and tothers
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'show_admin_column' => true,
'rewrite' => array( 'hierarchical' => true, 'slug' => 'institutions' ),
);
register_taxonomy( 'institutions', 'institution', $args );
}
add_action( 'init', 'my_taxonomies_institutions', 0 );
OK, there's a menu item Instituitions in admin zone, and a bit of Categories there, for example - Sections. Now in order to animate the theme that constructed for this taxonomy I need to go through all posts and to attach the Instituitions term to the post depending of it's post_type.
print term_exists('sections'); // 7
I tried the following
$ret = wp_set_post_terms($pid, 7, 'institution');
$ret = wp_set_post_terms($pid, 'sections', 'institution');
but result was
WP_Error Object ( [errors] => Array ( [invalid_taxonomy] => Array ( [0] => Неверная таксономия. ) ) [error_data] => Array ( ) )
What I'm doing wrong?
You registered taxonomy with name institutions but using institution by mistake, hence te error [invalid_taxonomy]. It should be like this
$ret = wp_set_post_terms($pid, array(7,), 'institutions');
$ret = wp_set_post_terms($pid, array('sections',), 'institutions');
To assign this term "sections" with term_id = 7 to all posts of type institution, do something like
$posts = get_posts(array(
'post_type' => 'institution',
'post_status' => 'publish',
'posts_per_page' => -1
));
foreach ( $posts as $post ) {
wp_set_post_terms( $post->ID, array(7,), 'institutions');
// OR
// wp_set_post_terms( $post->ID, array ('sections',), 'institutions');
}
I hope this will work.
Please have a look at this codex page for further info.
try something like:
$posts = get_posts([
'post_type' => 'institution',
'post_status' => 'publish',
'numberposts' => -1
]);
foreach ( $posts as $post ) {
wp_set_post_terms( $post->ID; array( ), 'institutions');
}
also if you want to wp_set_post_terms by id, you should use wp_set_post_terms( $post->ID; array( $id )) instead of wp_set_post_terms( $post->ID; $id) take a look here
Adding OptionTree pages is simple with the code below, but does anyone know how to retrieve the stored data?
/**
* Hook to register admin pages
*/
add_action( 'init', 'register_options_pages' );
/**
* Registers all the required admin pages.
*/
function register_options_pages() {
// Only execute in admin & if OT is installed
if ( is_admin() && function_exists( 'ot_register_settings' ) ) {
// Register the pages
ot_register_settings(
array(
array(
'id' => 'custom_options',
'pages' => array(
array(
'id' => 'test_page',
'parent_slug' => 'options-general.php',
'page_title' => 'Test Page',
'menu_title' => 'Test Page',
'capability' => 'edit_theme_options',
'menu_slug' => 'test-page',
'icon_url' => null,
'position' => null,
'updated_message' => 'Test Page updated.',
'reset_message' => 'Test Page reset.',
'button_text' => 'Save Changes',
'show_buttons' => true,
'screen_icon' => 'options-general',
'contextual_help' => null,
'sections' => array(
array(
'id' => 'test_section',
'title' => __( 'Test Section', 'motif-core' )
)
),
'settings' => array(
array(
'id' => 'test_section_input',
'label' => 'Test Input',
'desc' => 'Pretty freaking awesome!',
'std' => '',
'type' => 'text',
'section' => 'test_section',
'class' => ''
)
)
)
)
)
)
);
I tried this $my_plugin_options = get_option('custom_options'); but it only shows the word 'array' on the front end?
This is how to retrieve the stored data:
$my_plugin_options = get_option('custom_options');
echo $my_plugin_options['test_section_input'];
I am using CMB2's select to pull in a list of posts that a user can choose from in a custom meta box.
I have added a "blank" option to the options array, but I can't figure out how to make that the default option (ie. <option selected="selected" value="">I'm blank</option>).
I need to do this so I can use an if statement that says if the field is blank, don't show the output box on the site. Right now, even if the user hasn't specifically chosen an option, an option with a value is passed through.
Here's the meta box code:
$link_post_types = array('charter', 'page');
$meta_boxes['ms_metabox'] = array(
'id' => 'ms_metabox',
'title' => __( 'Page Links', 'cmb2' ),
'object_types' => array( 'page' ),
'context' => 'normal',
'priority' => 'high',
'show_names' => true,
'fields' => array(
array(
'name' => __( 'Page Link', 'cmb2' ),
'desc' => __( 'Choose the page this will link to', 'cmb2' ),
'id' => $prefix . 'page_link',
'type' => 'select',
'options' => ms_get_posttype_options($link_post_types),
),
),
);
function ms_get_posttype_options($argument) {
$get_post_args = array(
'post_type' => $argument,
'posts_per_page' => -1,
'orderby' => 'type',
'order' => ASC
);
$options = array();
foreach ( get_posts( $get_post_args ) as $post ) {
$post_type = get_post_type( $post->ID);
$title = get_the_title( $post->ID );
$permalink = get_permalink( $post->ID);
$options[] = array(
'name' => $title . ' : ' . $post_type,
'value' => $permalink,
);
}
$empty_option[] = array(
'name' => 'Please select an option',
'value' => '',
);
$options = array_merge($empty_option, $options);
return $options;
}
There is a default argument but when I tried to apply it as in the example, it didn't work.
Thanks for any help!
I halfway figured it out. The posts I was having problems with were old ones where I had already been messing with the values before I added the blank option - when I created new posts, the default option was the blank one (since it was the first array in the merge).
If anyone has a more foolproof solution I'd like to hear it though!
You can add the following to the meta box fields array:
show_option_none' => true