Show authors only own courses in dropdown - php

I am using Buddypress groups and part of the Group set up is to associate it to a Post (it's a custom post type called 'course').
The problem is that when associating a group to a particular post, the dropdown shows Authors all sitewide posts, (i.e. including from other authors). I want it so they can only see, and select from, their own posts - i.e. associate their group to one of their posts.
The code that is behind the current dropdown (which shows all authors' posts) is:
<select name="bp_group_course" id="bp-group-course">
<option value="-1"><?php _e( '--Select--', 'buddypress-learndash' ); ?></option>
<?php
foreach ( $courses as $course ) {
$group_attached = get_post_meta( $course->ID, 'bp_course_group', true );
if ( !empty( $group_attached ) && ( '-1' != $group_attached ) && $course->ID != $group_status ) {
continue;
}
?><option value="<?php echo $course->ID; ?>" <?php echo (( $course->ID == $group_status )) ? 'selected' : ''; ?>><?php echo $course->post_title; ?></option><?php
}
?>
</select>
$courses seems to come from:
if ( ! empty( $course_id ) ) {
$courses = array( get_post( $course_id ) );
} elseif ( ! empty( $group_id ) ){
$courses = learndash_group_enrolled_courses( $group_id );
$courses = array_map( 'intval', $courses );
$courses = ld_course_list( array( 'post__in' => $courses, 'array' => true ) );
} else {
$courses = ld_course_list( array( 'array' => true ) );
}
How can I limit it to just the currently logged in user's posts?
Thanks in advance,

Related

WordPress custom post meta filter not displaying options when filter is set

I have two custom post types set up - "Books" and "Authors". I am using custom metadata which allows you to link a book to an author via a select box (by querying posts from the authors post type to create the select options).
This works fine, but I'm also trying to create a custom filter on the posts screen for the books post type that allows you to filter by author, which isn't behaving as expected. Here's the code I'm using to add the filter:
function book_filter() {
global $typenow;
global $wp_query;
if ( $typenow == 'book' ) {
$authors = new WP_Query(
array(
'post_type' => 'author',
'nopaging' => true
)
);
wp_reset_postdata();
/*
$authors = get_posts( array(
'post_type' => 'author',
'numberposts' => -1
));
*/
$current_author = '';
if( isset( $_GET['author'] ) ) {
$current_author = $_GET['author'];
} ?>
<select name="author" id="author">
<option value="all" <?php selected( 'all', $current_author ); ?>>All authors</option>
<?php
if ($authors->have_posts()) {
while ($authors->have_posts()) {
$authors->the_post();
if ($current_author == get_the_ID()) {
echo '<option value="' . get_the_ID() . '" selected>' . get_the_title() . '</option>';
} else {
echo '<option value="' . get_the_ID() . '">' . get_the_title() . '</option>';
}
}
}
/* foreach( $authors as $author ) { ?>
<option value="<?php echo $author->ID; ?>" <?php selected( $author->ID, $current_author ); ?>><?php echo get_the_title($author->ID); ?></option>
<?php } */
?>
</select>
<?php }
}
add_action( 'restrict_manage_posts', 'book_filter' );
function do_book_filter( $query ) {
global $pagenow;
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
if ( is_admin() && $pagenow=='edit.php' && $post_type == 'book' ) {
if (isset( $_GET['author'] ) && $_GET['author'] !='all' ) {
$query->query_vars['meta_key'] = 'author';
$query->query_vars['meta_value'] = $_GET['author'];
$query->query_vars['meta_compare'] = '=';
}
}
}
add_filter( 'parse_query', 'do_book_filter' );
Initially, all the authors are shown in the filter, and selecting an author to filter by does actually work. The problem is that, once it's been filtered, the authors disappear from the select box dropdown. I tried adding an else statement to if ($authors->have_posts()) {... and this confirmed that it isn't fetching posts from the authors post type after a filter has been set.
I'm also using another custom filter (removed from the code for simplicity) which just uses a standard array variable rather than a query and that one is working fine, so I guess it must something to do with the custom post type query.
You'll see in the code that I've tried get_posts (commented) as well as WP_Query but they both present the same issue.
Where am I going wrong here?

Can't sanitize select field with WordPress Categories

I'm adding a custom field to page that would select a blog category to feature on that page. All the other fields are working fine, so, i'll post code related only to this field. Getting error 500 when loading page editor.
$feat_blog = isset( $values['feat_blog'] ) ? esc_attr( $values['feat_blog'][0] ) : "";
This is the field itself
<select name="feat_blog" id="feat_blog" value="<?php echo $feat_blog; ?>">
<?php $categories = get_categories(); foreach($categories as $category) { ?>
<option value="<?php echo $category->slug ?>"> <?php echo $category->name ?></option>
<?php } ?>
</select>
And sanitization code that's actually causing trouble
if ( isset( $_POST['feat_blog'] )){
$valid_values = array(
categories = get_categories();
foreach($categories as $category) {
echo $category->slug,
}
);
$value = sanitize_text_field( $_POST['feat_blog'] );
if( in_array( $value, $valid_values ) ) {
update_post_meta( $post->ID, 'feat_blog', $value );
}
}
There are quite a few things wrong with your code here...
You are putting ; in an array and attempting to assign a variable there.
You are echoing in an array.
You are running functions inside an array.
You are missing the $ infront of the $categories variable.
if ( isset( $_POST['feat_blog'] )) {
$categories = get_categories();
$valid_values = array();
foreach($categories as $category) {
$valid_values[] = $category->slug;
}
$value = sanitize_text_field( $_POST['feat_blog'] );
if( in_array( $value, $valid_values ) ) {
update_post_meta( $post->ID, 'feat_blog', $value );
}
}
What I did here is I moved the $categories variable declaration outside of the foreach loop and set the $valid_values array BEFORE the loop. If you set it inside the loop it is going to reset every time the loop occurs. You also can't use ; inside of an array as that is intended to close the statement.

Duplicate values appended each time save checkbox values

I am trying to create a multiselect dropdown list using "jQuery UI MultiSelect Widget" (http://www.erichynds.com/blog/jquery-ui-multiselect-widget) on Wordpress template page and save checked options into database (Mysql) as a single string value.
And THE PROBLEM: duplicate values are appended (i.e A, B, A, B) each time I click Save form. The problem does not happen IF I select new options in this dropdown list. BTW, other fields like textbox, single-select dropdown or textarea are OK.
Below are 2 code segments that I believe the problem comes from, so someone please help me point out what's going wrong here. I have been worked around this problem for the whole week but NO luck! Thank you very much!
<?php
case 'maker_dropdown':
global $wpdb;
$makers = $wpdb->get_var( $wpdb->prepare( "SELECT field_values FROM ". $wpdb->prefix . "cp_ad_fields WHERE field_name = 'cp_maker';", "" ) );
$selected_makers = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM ". $wpdb->prefix . "usermeta WHERE meta_key = 'maker' AND user_id =" . $user->ID . ";", "" ) );
if ($makers) {
?>
<select name="<?php echo $field_id; ?>[]" class="regular-dropdown multiselect" multiple="multiple" >
<?php
$options = explode( ',', $makers);
$selected_options = explode( ',', $selected_makers);
foreach ( $options as $option) { // loop thru all available options
if ( in_array($option, $selected_options)) {
?>
<option name="<?php echo $option; ?>[]" selected="selected" value="<?php esc_attr_e($the_value); ?>"><?php esc_attr_e($option); ?></option>
<?php
}
else {
?>
<option value="<?php esc_attr_e($option); ?>"><?php esc_attr_e($option); ?></option>
<?php
}
} //endforeach
?>
</select>
<?php } //endif ?>
break;
This code segment is used to display multiselect dropdown list on front-end.
function ctm_profile_fields_save($user_id) {
global $ctm_extra_profile_fields;
foreach ($ctm_extra_profile_fields as $field_id => $field_values) :
$selected_options = implode(',', $_POST[$field_id]);
if ($field_values['type'] == 'maker_dropdown') {
update_user_meta( $user_id, $field_id, $selected_options );
}
else {
update_user_meta( $user_id, $field_id, sanitize_text_field( $_POST[$field_id] ) );
}
endforeach;
}
add_action('personal_options_update', 'ctm_profile_fields_save');
add_action('edit_user_profile_update', 'ctm_profile_fields_save');
This code segment is used to save multiselect dropdown list into database.
update_user_meta function allows for multiple meta entries with the same key.
When you read the existing makers for the user you may get ['A', 'B']. When you save the submitted form you add a new set of selected values ['A', 'B'] to what was there previously. This is why your values are duplicated.
There are two easy ways of solving this.
Option 1: Clear the meta key before saving it.
foreach ($ctm_extra_profile_fields as $field_id => $field_values) :
$selected_options = implode(',', $_POST[$field_id]);
delete_user_meta($user_id, $field_id);
if ($field_values['type'] == 'maker_dropdown') {
update_user_meta( $user_id, $field_id, $selected_options );
}
else {
update_user_meta( $user_id, $field_id, sanitize_text_field( $_POST[$field_id] ) );
}
endforeach;
Option 2: Specify previous value in the update_user_meta to not create duplicate entries
foreach ($ctm_extra_profile_fields as $field_id => $field_values) :
$selected_options = implode(',', $_POST[$field_id]);
if ($field_values['type'] == 'maker_dropdown') {
update_user_meta( $user_id, $field_id, $selected_options, $selected_options );
}
else {
update_user_meta( $user_id, $field_id, sanitize_text_field( $_POST[$field_id] ), sanitize_text_field( $_POST[$field_id] ) );
}
endforeach;

How add a class to select element <option> tag in Contact Form 7?

I'm a big fan of Contact Form 7 and I always come to a point where I need to make a few extended customization to my forms. This time, I'm quite frustrated trying to add different classes to a select element <option> tag with no avail.
What I'm trying to do is implement a cool style and effect to dropdown lists from Here into my own CF7 form - as the screenshot shows it works nicely, however, icons are not showing because so that they can be displayed the <option>tag within a select element needs to have its own class.
For e.g:
First, I need to create a select element with id="cd-dropdown" and class="cd-select", until here, this can be easily achieved with the CF7 shortcode generator as bellow.
[select* select-profissao id:cd-dropdown class:cd-select "Professional" "Nurse" "Lawyer"]
Contact Form 7 aforementioned shortcode generates the html select element to something like this:
<select id="cd-dropdown" class="cd-select">
<option value="" selected>Professional</option>
<option value="" >Nurse</option>
<option value="" >Lawyer</option>
</select>
But I'd like to be able to add a class to the <option> tag. Is it even possible to achieve that by using the CF7 shortcode generator? Are there any workarounds in order to achieve that maybe by using javascript/jQuery or even PHP?
<select id="cd-dropdown" class="cd-select">
<option value="" selected>Professional</option>
<option value="" class="icon-nurse">Nurse</option>
<option value="" class="icon-lawyer">Lawyer</option>
</select>
I'd really appreciate any guidance regarding this issue.
Thanks in advance.
Just add this jquery:
http://jsfiddle.net/rvpatel/7wa3V/
$( "#cd-dropdown option" ).addClass(function(index) {
return "icon-" + $(this).text().toLowerCase().split(' ').join('-');
});
I think it would be easier to add classes to option client side using jQuery (assuming you are already using jQuery for the SimpleDropDownEffects plugin)
Example Select rendered by contact form:
<select id="cd-dropdown" class="cd-select">
<option value="-1" selected>Choose a weather condition</option>
<option value="1">Sun</option>
<option value="2">Clouds</option>
<option value="3">Snow</option>
<option value="4">Rain</option>
<option value="5">Windy</option>
</select>
Add following javascript on the page:
jQuery(document).ready(function() {
myClassNames = ["", "icon-sun", "icon-cloudy", "icon-weather", "icon-rainy", "icon-windy"];
jQuery.each(jQuery("#cd-dropdown option"), function(index, value) {
jQuery(value).addClass(myClassNames[index]);
});
//do SimpleDropDownEffects plugin here after classes are added.
});
Pros: No hacking into plugin files, no update plugin woes.
Cons: class names are had-coded in js
Modify in your plugin dir modules/select.php wpcf7_select_shortcode_handler function:
function wpcf7_select_shortcode_handler( $tag ) {
$tag = new WPCF7_Shortcode( $tag );
if ( empty( $tag->name ) )
return '';
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error )
$class .= ' wpcf7-not-valid';
$atts = array();
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_option( 'id', 'id', true );
$atts['tabindex'] = $tag->get_option( 'tabindex', 'int', true );
if ( $tag->is_required() )
$atts['aria-required'] = 'true';
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$defaults = array();
if ( $matches = $tag->get_first_match_option( '/^default:([0-9_]+)$/' ) )
$defaults = explode( '_', $matches[1] );
$multiple = $tag->has_option( 'multiple' );
$include_blank = $tag->has_option( 'include_blank' );
$first_as_label = $tag->has_option( 'first_as_label' );
$name = $tag->name;
$values = $tag->values;
$labels = $tag->labels;
$empty_select = empty( $values );
if ( $empty_select || $include_blank ) {
array_unshift( $labels, '---' );
array_unshift( $values, '' );
} elseif ( $first_as_label ) {
$values[0] = '';
}
$html = '';
$posted = wpcf7_is_posted();
foreach ( $values as $key => $value ) {
$selected = false;
// changed here
if (! ( $attributes = json_decode($value, true) ) ) {
$attributes = array(
'value' => $value
);
} else {
$value = (isset($attributes['value'])) ? $attributes['value'] : null;
}
if ( $posted && ! empty( $_POST[$name] ) ) {
if ( $multiple && in_array( esc_sql( $value ), (array) $_POST[$name] ) )
$selected = true;
if ( ! $multiple && $_POST[$name] == esc_sql( $value ) )
$selected = true;
} else {
if ( ! $empty_select && in_array( $key + 1, (array) $defaults ) )
$selected = true;
}
// changed here
$item_atts = array('selected' => $selected ? 'selected' : '' );
$item_atts = array_merge($attributes, $item_atts);
$item_atts = wpcf7_format_atts( $item_atts );
$label = isset( $labels[$key] ) ? $labels[$key] : $value;
$html .= sprintf( '<option %1$s>%2$s</option>',
$item_atts, esc_html( $label ) );
}
if ( $multiple )
$atts['multiple'] = 'multiple';
$atts['name'] = $tag->name . ( $multiple ? '[]' : '' );
$atts = wpcf7_format_atts( $atts );
$html = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select>%4$s</span>',
$tag->name, $atts, $html, $validation_error );
return $html;
}
Now you can call the plugin as before, or send the value of json(all keys rendered as attribute), i.e.:
[select* select-profissao id:cd-dropdown class:cd-select '{"value":"Professional","class":"mytestclass"}' '{"value":"Nurse","more-attr":"Nurse Attribute"}']
Unfortunately I can not test this (No installed wordpress).

WooCommerce Filter Orders by Item Count

Is it possible to create a custom filter in WooCommerce Orders Admin which will allow filtering by the order item count?
We are looking to filter orders with either one item or more than one item (multiple items).
We have the dropdown on the page via the following action and function, but we're stuck on the filter part and how to query each order to find the item count.
add_action( 'restrict_manage_posts', 'filter_multi_item_orders', 50 );
function filter_multi_item_orders() {
global $typenow;
if ( 'shop_order' != $typenow ) {
return;
}?>
<select name='multi_order_view' id='dropdown_multi_order_view'>
<option <?php
if ( isset( $_GET['multi_order_view'] ) && $_GET['multi_order_view'] ) {
selected( 'all', $_GET['multi_order_view'] );
}
?> value="all"><?php esc_html_e( 'Single and Multi Orders', 'show_multipet_orders' ); ?></option>
<option <?php
if ( isset( $_GET['multi_order_view'] ) && $_GET['multi_order_view'] ) {
selected( 'single', $_GET['multi_order_view'] );
}
?>value="single"><?php esc_html_e( 'Single Orders Only', 'show_multipet_orders' ); ?></option>
<option <?php
if ( isset( $_GET['multi_order_view'] ) && $_GET['multi_order_view'] ) {
selected( 'multi', $_GET['multi_order_view'] );
}
?>value="multi"><?php esc_html_e( 'Multi Orders Only', 'show_multipet_orders' ); ?></option>
</select>
<?php
}
add_filter( 'request', 'filter_multi_item_orders_query', 100 );
function filter_multi_item_orders_query( $vars ) {
global $typenow;
$key = 'post__not_in';
if ( 'shop_order' == $typenow && isset( $_GET['multi_order_view'] ) ) {
if ( 'single' == $_GET['multi_order_view'] ) {
// return orders with $order->get_item_count() == 1
}
elseif ( 'multi' == $_GET['multi_order_view'] ) {
// return orders with $order->get_item_count() > 1
}
}
return $vars;
}
This may not be the best/a possible approach but hope someone can shed some light.
Many thanks

Categories