How to get the first topic in a lesson in learndash - wordpress

I want to retrieve the first topic in a lesson in learndash and redirect it through it. But for some reason am not sure how to do it.
I checked the API and doesn't see any appropriate filter/hook for it.
Here is my code:
function redirect_to_first_topic() {
// We only want to do this for Topics. But the below code can be adapted to work for Lessons
global $post;
$post_id = $post->ID;
if ( get_post_type( $post_id ) == 'sfwd-lessons' ) {
$progress = learndash_get_course_progress( null, $post_id );
$link = $progress['next'];
$parent_lesson_id = learndash_get_setting( $post, 'topic' );
$parent_lesson = get_post( $parent_lesson_id );
var_dump($parent_lesson);
}
// Always return $link
// return $link;
}
add_action('wp', 'redirect_to_first_topic');
So basically what am doing here is getting the parent which is the lesson.

A bit late, but mb it will help someone else. You can see how to get 1. lesson of a course and go deeper if needed fe. first topic of first lesson and so on :
add_action( 'template_redirect', 'course_overview_redirect' );
function course_overview_redirect() {
global $post;
if ( ! empty( $post ) && $post->post_type == 'sfwd-courses' && ! empty( $post->ID ) ) {
$lessons = learndash_get_course_lessons_list( $post->ID );
if ( ! empty( $lessons ) ) {
$lesson = array_shift( $lessons );
if ( ! empty( $lesson ) ) {
$url = get_permalink( $lesson[ "post" ]->ID );
if ( ! empty( $url ) ) {
wp_redirect( esc_url( $url ) ); // And redirect if needed
exit;
}
}
}
}
}

You can add a button like this;
$args = array(
'posts_per_page' => -1,
'post_type' => 'sfwd-lessons', // you can change here to find topics : 'sfwd-topics'
'suppress_filters' => true,
'fields' => 'ids',
'orderby' => 'menu_order', // ordering by menu_order will show lesson list, in their order in course.
'order' => 'ASC',
// this meta query is used if you want to search a lesson under a course, or if you search for a topic which is in a course but not under a lesson
'meta_query' => array(
array(
'key' => 'course_id',
'value' => $course_id, // this is id of your course
)
// if your topic is under a lesson than you should add lesson meta query
// your meta query should be changed like below
/*
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'course_id',
'value' => $course_id,
),
array(
'key' => 'lesson_id',
'value' => $lesson_id,
),
),
*/
),
);
$all_lessons = get_posts($args);
$first_lesson = $all_lessons[0]; // taking directly first element of array
$button_html = '' . __( 'Start the course', 'custom-text' ) . '';

Related

Why attribute from shortcode doesn't work?

I have such code with attribute extraction to use it in shortcode.
<?php
function wpusers_shortcode( $atts ) {
extract(shortcode_atts( array(
'Department' => '',
), $atts
)
);
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'Department',
'value' => $Department,
),
)
);
// The Query
$user_query = new WP_user_Query( $args );
// User Loop
if ( ! empty( $user_query->get_results() ) ) {
foreach ( $user_query->get_results() as $user ) {
echo '<p>' . $user->display_name . '</p>';
}
} else {
echo 'No users found.';
}
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );
?>
The shortcode is [wpusers Department="IEDK"].
Users are assigned to custom field Department
enter image description here
But at front end I have a message - No Users Found.
When I add attr (IEDK) in the code I can see them
extract(shortcode_atts( array(
'Department' => 'IEDK',
or
'key' => 'Department',
'value' => 'IEDK',
Whhere can be a problem?
Thanks in advance.
Remove extract and then try to debug with uncomment lines
function wpusers_shortcode( $atts ) {
$ar = shortcode_atts(
array('Department' => ''),
$atts
);
// print_r($ar); die;
$args = array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'Department',
'value' => $ar['Department'],
),
)
);
// print_r($args); die;
$user_query = new WP_user_Query( $args );
if ( ! empty( $user_query->get_results() ) ) {
foreach ( $user_query->get_results() as $user ) {
echo '<p>' . $user->display_name . '</p>';
}
} else {
echo 'No users found.';
}
}
add_shortcode( 'wpusers', 'wpusers_shortcode' );
Solved.
The problem was in Uppercase of key [wpusers Department="IEDK"].
I changed to small "d" everywhere and now it works..........

WC Vendors - Custom Taxonomy Checklist Not Saving on Front-End

I'm using WC Vendors and have output the taxonomy named "location" on the products using wp_term_checklist per their suggestion. I've got it saving to the product, but it's not saving the checkbox selection on the front-end.
This is the code I've added to the product-edit.php template
$args = array(
'descendants_and_self' => 0,
'selected_cats' => false,
'popular_cats' => false,
'walker' => null,
'taxonomy' => 'location',
'checked_ontop' => false
);
wp_terms_checklist( $my_postid, $args );
$post_to_edit = array(
'ID' => $my_postid,
'tax_input' => array( 'location' => array($_POST['tax_input']['location']) )
);
$pid = wp_update_post($post_to_edit);
if ( isset($_POST['tax_input']['location']) && is_array( $_POST['tax_input']['location'] ) ) {
$location = array_map( 'intval', $_POST['tax_input']['location'] );
$location = array_unique( $location );
wp_set_post_terms($pid, $location, 'location');
}
This is their code where they use a multi-select, but we need checkboxes:
https://gist.github.com/digitalchild/128033d2d41f682acd4387b595d4f607
We have a custom terms checklist called wcv_terms_checklist() in our form helper. It didn't support custom taxonomies but I have modified it to support that now. You can use the following code from v1.7.10 and above to get working custom terms checklists on our front end.
// Output the location checklist
function form_location( $object_id ) {
$args = array(
'taxonomy' => 'location',
);
$field = array(
'id' => 'product_loc_list',
'label' => __( 'Location', 'wcvendors-pro' ),
'class' => 'product_cat_checklist',
);
WCVendors_Pro_Form_Helper::wcv_terms_checklist( $object_id, $args, $field );
}
add_action( 'wcv_after_product_details', 'form_location' );
// Save the terms
function save_location( $post_id ){
if ( isset( $_POST[ 'location' ] ) && is_array( $_POST[ 'location' ] ) ) {
$location = array_map( 'intval', $_POST[ 'location' ] );
$location = array_unique( $location );
wp_set_post_terms( $post_id, $location, 'location' );
}
}
add_action( 'wcv_save_product', 'save_location' );
Gist available here - https://gist.github.com/digitalchild/09e15649425845fef0b8d3af75c79dd1

Wordpress API - how to show different data in singular vs plural custom post type responses

I have a custom post type 'product' that returns quite a lot of data in the API response, up to 400 posts with a lot of nodes. Almost all the data is coming from advanced custom fields (I'm using ACF to API plugin to expose it).
On the 'products' page, I only need to show the title & image of the product. Is there a way to remove all other fields when requesting all products with https://example.com/wp-json/wp/v2/product, but leave that data in place when requesting a specific product with https://example.com/wp-json/wp/v2/product/123 ?
You better create a custom endpoint for all products. Add the code below in your custom plugin or add it in functions.php of theme (I will recommend the custom plugin approach though)
You can then access it using https://example.com/wp-json/custom/v1/all-products
add_action( 'rest_api_init', 'rest_api_get_all_products' );
function rest_api_get_all_products() {
register_rest_route( 'custom/v1', '/all-products', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'rest_api_get_all_products_callback',
'args' => array(
'page' => array(
'sanitize_callback' => 'absint'
),
'posts_per_page' => array(
'sanitize_callback' => 'absint'
)
)
));
}
function rest_api_get_all_products_callback( $request ) {
$posts_data = array();
$paged = $request->get_param( 'page' );
$posts_per_page = $request->get_param( 'posts_per_page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
$posts_per_page = ( isset( $posts_per_page ) || ! ( empty( $posts_per_page ) ) ) ? $posts_per_page : 10;
$query = new WP_Query( array(
'paged' => $paged,
'posts_per_page' => $posts_per_page,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'post_type' => array( 'product' )
)
);
$posts = $query->posts;
if( empty( $posts ) ){
return new WP_Error( 'no_post_found', 'No Products Found.', array( 'status' => 404 ) );
}
foreach( $posts as $post ) {
$id = $post->ID;
$post_thumbnail = ( has_post_thumbnail( $id ) ) ? get_the_post_thumbnail_url( $id ) : null;
$posts_data[] = (object) array(
'id' => intval($id),
'title' => $post->post_title,
'featured_img' => $post_thumbnail
);
}
$response = rest_ensure_response( $posts_data );
return $response;
}

How to create custom taxonomy field searchable?

I have added custom taxonomy field on tags, but when I search that field search is not working. Any way to make it searchable in WordPress dashboard?
Here’s the code. You can change $post_type and $custom_fields according to your needs.
function extend_admin_search( $query ) {
// Extend search for document post type
$post_type = 'document';
// Custom fields to search for
/* $custom_fields = array(
"_file_name",
); */
if( ! is_admin() )
return;
if ( $query->query['post_type'] != $post_type )
return;
$search_term = $query->query_vars['s'];
// Set to empty, otherwise it won't find anything
$query->query_vars['s'] = '';
/* if ( $search_term != '' ) {
$meta_query = array( 'relation' => 'OR' );
foreach( $custom_fields as $custom_field ) {
array_push( $meta_query, array(
'key' => $custom_field,
'value' => $search_term,
'compare' => 'LIKE'
));
}
$query->set( 'meta_query', $meta_query );
}; */
$query->set( 's', $search_term );
}
add_action( 'pre_get_posts', 'extend_admin_search' );

"used for variations" switch programmatically

There are 860+ products with different variations. The task is to allow user bulk edit "used for variations" field for some attributes. For example, we have size, gender that is still needed for variations, but also we have material, that is needed for filters only, so deleting this attribute is not a solution.
Totally untested and not particularly ideal if you have a lot of products as it could time out, but theoretically you could loop through all the variable products and update the _product_attributes meta value. I highly suggest you have a data backup and/or do this is a staging site.
function so_41978670_run_once(){
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'post_type',
'field' => 'slug',
'terms' => 'variable',
),
),
);
$products = new WP_Query( $args );
if( $products->have_posts() ){
while ( $products->have_posts() ) {
$products->the_post();
$product_id = get_the_ID();
$product = wc_get_product( $product_id );
$attributes = $product->get_attributes();
$meta_values = array();
if ( $attributes ) {
foreach ( $attributes as $attribute_key => $attribute ) {
if( in_array( $attribute_key, array( 'size', 'gender' ) ) ){
// Modify the attributes meta.
$attributes[ $attribute_key ]['is_variation'] = 1;
}
}
}
update_post_meta( $product->get_id(), '_product_attributes', $attributes );
}
wp_reset_postdata();
}
}
Potential update for WooCommerce 3.0 CRUD functions, but still untested:
function so_41978670_run_once() {
$args = array(
'limit' => -1,
'type' => 'variable',
);
$products = wc_get_products( $args );
if( ! empty ( $products ) ) {
foreach ( $products as $product ) {
$attributes = $product->get_attributes();
if ( $attributes ) {
foreach ( $attributes as $attribute_key => $attribute ) {
if( in_array( $attribute_key, array( 'size', 'gender' ) ) ){
// Modify the attribute settings.
$attribute->set_variation( true );
}
}
}
$product->set_attributes( $attributes );
$product->save();
}
}
}
add_action( 'admin_init', 'so_41978670_run_once' );

Resources