ID ) :
$stamp = wp_kses_post( __( 'Submitted on: %1$s', 'learndash' ) );
$date = date_i18n( $datef, strtotime( $essay->post_date ) );
endif;
if ( $can_publish ) : // Contributors don't get to choose the date of publish ?>
ID ) ) :
if ( ! EMPTY_TRASH_DAYS ) :
$delete_text = esc_html__( 'Delete Permanently', 'learndash' );
else :
$delete_text = esc_html__( 'Move to Trash', 'learndash' );
endif;
?>
post_author, '_sfwd-quizzes', true );
if ( ( !empty( $users_quiz_data ) ) && ( is_array( $users_quiz_data ) ) ) {
if ( ( $essay ) && ( is_a( $essay, 'WP_Post' ) ) ) {
$essay_quiz_time = get_post_meta( $essay->ID, 'quiz_time', true );
} else {
$essay_quiz_time = null;
}
foreach ( $users_quiz_data as $quiz_data ) {
// We check for a match on the quiz time from the essay postmeta first.
// If the essay_quiz_time is not empty and does NOT match then continue;
if ( ( absint( $essay_quiz_time ) ) && ( isset( $quiz_data['time'] ) ) && ( absint( $essay_quiz_time ) !== absint( $quiz_data['time'] ) ) ) {
continue;
}
if (empty($quiz_data['pro_quizid']) || $quiz_id != $quiz_data['pro_quizid'] || ! isset( $quiz_data['has_graded'] ) || false == $quiz_data['has_graded'] ) {
continue;
}
if ((isset($quiz_data['graded'])) && (!empty($quiz_data['graded']))) {
foreach ( $quiz_data['graded'] as $key => $graded_question ) {
if ( ( $key == $question_id ) && ( $essay->ID == $graded_question['post_id'] ) ) {
return $quiz_data['graded'][ $key ];
}
}
}
}
}
}
/**
* Update a users essay and quiz data on save post
*
* @since 2.2.0
*
* @param int $essay_id
* @param WP_Post $essay
* @param bool $update
*/
function learndash_save_essay_status_metabox_data( $essay_id, $essay, $update ) {
if ( ! isset( $_POST['question_id'] ) || empty( $_POST['question_id'] ) ) {
return;
}
$quiz_id = intval( $_POST['quiz_id'] );
$question_id = intval( $_POST['question_id'] );
$submitted_essay = learndash_get_submitted_essay_data( $quiz_id, $question_id, $essay );
if ( ( isset( $_POST['essay_quiz_post_id'] ) ) && ( !empty( $_POST['essay_quiz_post_id'] ) ) ) {
$essay_quiz_post_id = intval( $_POST['essay_quiz_post_id'] );
update_post_meta( $essay_id, 'quiz_post_id', $essay_quiz_post_id );
}
$quiz_score_difference = 0;
if ( isset( $_POST['post_status'] ) ) {
if ( ( $_POST['post_status'] != $submitted_essay['status'] ) ) {
if ( $_POST['post_status'] == 'graded' )
$quiz_score_difference = 1;
else if ( $_POST['post_status'] == 'not_graded' )
$quiz_score_difference = -1;
}
}
$submitted_essay['status'] = esc_html( $_POST['post_status'] );
$submitted_essay['points_awarded'] = intval( $_POST['points_awarded'] );
/**
* Filter essay status data
*/
$submitted_essay = apply_filters( 'learndash_essay_status_data', $submitted_essay );
learndash_update_submitted_essay_data( $quiz_id, $question_id, $essay, $submitted_essay );
$original_points_awarded = isset( $_POST['original_points_awarded'] ) ? intval( $_POST['original_points_awarded'] ) : null;
$points_awarded = isset( $_POST['points_awarded'] ) ? intval( $_POST['points_awarded'] ) : null;
if ( ! is_null( $original_points_awarded ) && ! is_null( $points_awarded ) ) {
if ( $points_awarded > $original_points_awarded ) {
$points_awarded_difference = intval( $points_awarded ) - intval( $original_points_awarded );
} else {
$points_awarded_difference = ( intval( $original_points_awarded ) - intval( $points_awarded ) ) * -1;
}
$updated_scoring = array(
'updated_question_score' => $points_awarded,
'points_awarded_difference' => $points_awarded_difference,
'score_difference' => $quiz_score_difference
);
/**
* Filter updated scoring data
*/
$updated_scoring = apply_filters( 'learndash_updated_essay_scoring', $updated_scoring );
learndash_update_quiz_data( $quiz_id, $question_id, $updated_scoring, $essay );
/**
* Perform action after all the quiz data is updated
*/
do_action( 'learndash_essay_all_quiz_data_updated', $quiz_id, $question_id, $updated_scoring, $essay );
}
}
add_action( 'save_post_sfwd-essays', 'learndash_save_essay_status_metabox_data', 10, 3 );
/**
* Updates a users submitted essay data
*
* Finds the essay in this particular quiz attempt in the users meta and updates its data
*
* @since 2.2.0
*
* @param int $quiz_id
* @param int $question_id
* @param WP_Post $essay
* @param array $submitted_essay
*/
function learndash_update_submitted_essay_data( $quiz_id, $question_id, $essay, $submitted_essay ) {
$users_quiz_data = get_user_meta( $essay->post_author, '_sfwd-quizzes', true );
if ( ( $essay ) && ( is_a( $essay, 'WP_Post' ) ) ) {
$essay_quiz_time = get_post_meta( $essay->ID, 'quiz_time', true );
} else {
$essay_quiz_time = null;
}
$quizdata_changed = array();
foreach ( $users_quiz_data as $quiz_key => $quiz_data ) {
// We check for a match on the quiz time from the essay postmeta first.
// If the essay_quiz_time is not empty and does NOT match then continue;
if ( ( absint( $essay_quiz_time ) ) && ( isset( $quiz_data['time'] ) ) && ( absint( $essay_quiz_time ) !== absint( $quiz_data['time'] ) ) ) {
continue;
}
if ( $quiz_id != $quiz_data['pro_quizid'] || ! isset( $quiz_data['has_graded'] ) || false == $quiz_data['has_graded'] ) {
continue;
}
foreach ( $quiz_data['graded'] as $question_key => $graded_question ) {
if ( ( $question_key == $question_id ) && ( $essay->ID == $graded_question['post_id'] ) ) {
$users_quiz_data[ $quiz_key ]['graded'][ $question_key ] = $submitted_essay;
if ( ( isset( $submitted_essay['status'] ) ) && ( 'graded' === $submitted_essay['status'] ) ) {
$quizdata_changed[] = $users_quiz_data[ $quiz_key ];
}
}
}
}
update_user_meta( $essay->post_author, '_sfwd-quizzes', $users_quiz_data );
/**
* Perform action after essay response data is updated
*/
do_action( 'learndash_essay_response_data_updated', $quiz_id, $question_id, $essay, $submitted_essay );
}
/**
* Updates a users quiz data
*
* Finds this particular quiz attempt in the users meta and updates its data
*
* @since 2.2.0
*
* @param int $quiz_id
* @param int $question_id
* @param array $updated_scoring
* @param WP_Post $essay
*/
function learndash_update_quiz_data( $quiz_id, $question_id, $updated_scoring, $essay ) {
$affected_quiz_keys = array();
$users_quiz_data = get_user_meta( $essay->post_author, '_sfwd-quizzes', true );
if ( ( $essay ) && ( is_a( $essay, 'WP_Post' ) ) ) {
$essay_quiz_time = get_post_meta( $essay->ID, 'quiz_time', true );
} else {
$essay_quiz_time = null;
}
// We need to find the user meta quiz to matches the essay being scored.
foreach ( $users_quiz_data as $quiz_key => $quiz_data ) {
// We check for a match on the quiz time from the essay postmeta first.
// If the essay_quiz_time is not empty and does NOT match then continue;
if ( ( absint( $essay_quiz_time ) ) && ( isset( $quiz_data['time'] ) ) && ( absint( $essay_quiz_time ) !== absint( $quiz_data['time'] ) ) ) {
continue;
}
if ( ( $quiz_id != $quiz_data['pro_quizid'] ) || ( !isset( $quiz_data['has_graded'] ) ) || ( false == $quiz_data['has_graded'] ) )
continue;
if ( ( !isset( $quiz_data['graded'][$question_id]['post_id'] ) ) || ( $quiz_data['graded'][$question_id]['post_id'] != $essay->ID ) )
continue;
$affected_quiz_keys[] = $quiz_key;
// update total score
$users_quiz_data[ $quiz_key ]['score'] = $users_quiz_data[ $quiz_key ]['score'] + $updated_scoring['score_difference'];
// update total points
$users_quiz_data[ $quiz_key ]['points'] = $users_quiz_data[ $quiz_key ]['points'] + $updated_scoring['points_awarded_difference'];
// update total score percentage
$updated_percentage = ( $users_quiz_data[ $quiz_key ]['points'] / $users_quiz_data[ $quiz_key ]['total_points'] ) * 100;
$users_quiz_data[ $quiz_key ]['percentage'] = round( $updated_percentage, 2 );
// update passing score
$quizmeta = get_post_meta( $quiz_data['quiz'], '_sfwd-quiz', true );
$passingpercentage = intVal( $quizmeta['sfwd-quiz_passingpercentage'] );
$users_quiz_data[ $quiz_key ]['pass'] = ( $users_quiz_data[ $quiz_key ]['percentage'] >= $passingpercentage ) ? 1 : 0;
learndash_update_quiz_statistics( $quiz_id, $question_id, $updated_scoring, $essay, $users_quiz_data[ $quiz_key ] );
learndash_update_quiz_activity( $essay->post_author, $users_quiz_data[ $quiz_key ] );
}
update_user_meta( $essay->post_author, '_sfwd-quizzes', $users_quiz_data );
if ( !empty( $affected_quiz_keys ) ) {
foreach( $affected_quiz_keys as $quiz_key ) {
if ( isset( $users_quiz_data[ $quiz_key ] ) ) {
$send_quiz_completed = true;
if ( ( isset( $users_quiz_data[ $quiz_key ]['has_graded'] ) ) && ( true === $users_quiz_data[ $quiz_key ]['has_graded'] ) ) {
if ( ( isset( $users_quiz_data[ $quiz_key ]['graded'] ) ) && ( ! empty( $users_quiz_data[ $quiz_key ]['graded'] ) ) ) {
foreach ( $users_quiz_data[ $quiz_key ]['graded'] as $grade_item ) {
if ( ( isset( $grade_item['status'] ) ) && ( $grade_item['status'] !== 'graded' ) ) {
$send_quiz_completed = false;
}
}
}
}
if ( true === $send_quiz_completed ) {
if ( isset( $users_quiz_data[ $quiz_key ]['course'] ) )
$course_id = intval( $users_quiz_data[ $quiz_key ]['course'] );
else
$course_id = learndash_get_course_id( $essay->ID );
learndash_process_mark_complete( $essay->post_author, $users_quiz_data[ $quiz_key ]['quiz'], false, $course_id );
do_action( 'learndash_quiz_completed', $users_quiz_data[ $quiz_key ], get_user_by( 'ID', $essay->post_author ) );
/*
if ( ( isset( $users_quiz_data[ $quiz_key ]['topic'] ) ) && ( ! empty( $users_quiz_data[ $quiz_key ]['topic'] ) ) ) {
learndash_process_mark_complete( $essay->post_author, absint( $users_quiz_data[ $quiz_key ]['topic'] ), false, $course_id );
}
*/
/*
if ( ( isset( $users_quiz_data[ $quiz_key ]['lesson'] ) ) && ( ! empty( $users_quiz_data[ $quiz_key ]['lesson'] ) ) ) {
learndash_process_mark_complete( $essay->post_author, absint( $users_quiz_data[ $quiz_key ]['lesson'] ), false, $course_id );
}
*/
}
}
}
}
/**
* Perform action after essay quiz data is updated
*/
do_action( 'learndash_essay_quiz_data_updated', $quiz_id, $question_id, $updated_scoring, $essay );
}
function learndash_update_quiz_activity( $user_id = 0, $quiz_data = array() ) {
if ( ( !empty( $user_id ) ) && ( !empty( $quiz_data ) ) ) {
$quiz_data_meta = $quiz_data;
// Remove many fields that we either don't need or are duplicate of the main table columns
unset($quiz_data_meta['quiz']);
unset($quiz_data_meta['pro_quizid']);
unset($quiz_data_meta['time']);
unset($quiz_data_meta['completed']);
unset($quiz_data_meta['started']);
//unset($quiz_data_meta['graded']);
if ($quiz_data_meta['rank'] == '-')
unset($quiz_data_meta['rank']);
if ( $quiz_data['pass'] == true )
$quiz_data_pass = true;
else
$quiz_data_pass = false;
learndash_update_user_activity(
array(
'course_id' => (isset( $quiz_data['course'] ) ) ? intval( $quiz_data['course'] ) : 0,
'post_id' => $quiz_data['quiz'],
'user_id' => $user_id,
'activity_type' => 'quiz',
'activity_status' => $quiz_data_pass,
'activity_started' => $quiz_data['started'],
'activity_completed' => $quiz_data['completed'],
'activity_meta' => $quiz_data_meta,
)
);
}
}
/**
* Update the quiz statistics for this quiz attempt
*
* Updates the score when the essay grading is adjusted, I ran this through manual SQL queries
* because WpProQuiz doesn't offer an elegant way to grab a particular question and update it.
*
* @since 2.2.0
*
* @param int $quiz_id
* @param int $question_id
* @param array $updated_quiz_data
* @param WP_Post $essay
*/
function learndash_update_quiz_statistics( $quiz_id, $question_id, $updated_quiz_data, $essay, $users_quiz_data ) {
global $wpdb;
if ( ( isset( $users_quiz_data['statistic_ref_id'] ) ) && ( ! empty( $users_quiz_data['statistic_ref_id'] ) ) ) {
$refId = absint( $users_quiz_data['statistic_ref_id'] );
} else {
$refId = $wpdb->get_var(
$wpdb->prepare("
SELECT statistic_ref_id
FROM ". LDLMS_DB::get_table_name( 'quiz_statistic_ref' ) ." WHERE quiz_id = %d AND user_id = %d
", $quiz_id, $essay->post_author)
);
$refId = absint( $refId );
}
$row = $wpdb->get_results(
$wpdb->prepare("
SELECT *
FROM ". LDLMS_DB::get_table_name( 'quiz_statistic' ) ." WHERE statistic_ref_id = %d AND question_id = %d
", $refId, $question_id)
);
if ( empty( $row ) ) {
return;
}
if ( $updated_quiz_data['updated_question_score'] > 0 ) {
$correct_count = 1;
$incorrect_count = 0;
} else {
$correct_count = 0;
$incorrect_count = 1;
}
$update = $wpdb->update(
LDLMS_DB::get_table_name( 'quiz_statistic' ),
array(
'correct_count' => $correct_count,
'incorrect_count' => $incorrect_count,
'points' => $updated_quiz_data['updated_question_score'],
),
array(
'statistic_ref_id' => $refId,
'question_id' => $question_id,
),
array( '%d', '%d', '%d' ),
array( '%d', '%d' )
);
do_action( 'learndash_essay_question_stats_updated' );
}
/**
* Restrict assignment listings view to group leader only
*
* @since 2.2.0
*
* @param object $query WP_Query
* @return object $query WP_Query
*/
function learndash_restrict_essay_listings_for_group_admins( $query ) {
global $pagenow, $typenow;
if ( !is_admin() ) return;
if ( $pagenow != 'edit.php' ) return;
if ( !$query->is_main_query() ) return;
if ( empty( $typenow ) ) return;
if ( $typenow != 'sfwd-essays' ) return;
$q_vars = & $query->query_vars;
$user_id = get_current_user_id();
if ( learndash_is_group_leader_user( $user_id ) ) {
$group_ids = learndash_get_administrators_group_ids( $user_id );
$course_ids = array();
$user_ids = array();
if ( ! empty( $group_ids ) && is_array( $group_ids ) ) {
foreach( $group_ids as $group_id ) {
$group_course_ids = learndash_group_enrolled_courses( $group_id );
if ( ! empty( $group_course_ids ) && is_array( $group_course_ids ) ) {
$course_ids = array_merge( $course_ids, $group_course_ids );
}
$group_users = learndash_get_groups_user_ids( $group_id );
if ( ! empty( $group_users ) && is_array( $group_users ) ) {
foreach( $group_users as $group_user_id ) {
$user_ids[ $group_user_id ] = $group_user_id;
}
}
}
}
if ( ! empty( $course_ids ) && count( $course_ids ) ) {
if (!isset( $q_vars['meta_query'] ) )
$q_vars['meta_query'] = array();
$q_vars['meta_query'][] = array(
'key' => 'course_id',
'value' => $course_ids,
'compare' => 'IN',
);
}
if ( ! empty( $user_ids ) && count( $user_ids ) ) {
$q_vars['author__in'] = $user_ids;
} else {
$q_vars['author__in'] = - 2;
}
}
}
add_filter( 'parse_query', 'learndash_restrict_essay_listings_for_group_admins' );
/**
* AJAX callback for Uploading a file for an essay quesiton
*
* @since 2.2.0
*
* Runs checks for needing information, or will die and send an error back to browser
*/
function learndash_upload_essay() {
if ( ! isset( $_POST['nonce'] ) || ! isset( $_POST['question_id'] ) || ! isset( $_FILES['essayUpload'] ) ) {
wp_send_json_error();
die();
}
$nonce = $_POST['nonce'];
$question_id = intval( $_POST['question_id'] );
if ( empty( $question_id ) ) {
wp_send_json_error();
die();
}
/**
* Changes in v2.5.4 to include the question_id as part of the nonce
*/
if ( ! wp_verify_nonce( $nonce, 'learndash-upload-essay-'. $question_id ) ) {
wp_send_json_error();
die( 'Security check' );
} else {
if ( !is_user_logged_in() ) {
if ( !apply_filters('learndash_essay_upload_user_check', false, $question_id ) ) {
wp_send_json_error();
die();
}
}
$file_desc = learndash_essay_fileupload_process( $_FILES['essayUpload'], $question_id );
if ( ! empty( $file_desc ) ) {
wp_send_json_success( $file_desc );
} else {
wp_send_json_error();
}
die();
}
}
add_action( 'wp_ajax_learndash_upload_essay', 'learndash_upload_essay' );
add_action( 'wp_ajax_nopriv_learndash_upload_essay', 'learndash_upload_essay' );
/**
* Upload files for essays
*
* @since 2.2.0
*
* @param array $uploadfiles
* @param int $question_id
*
* @return array file description
* @internal param int $post_id assignment id
*/
function learndash_essay_fileupload_process( $uploadfiles, $question_id ) {
if ( is_array( $uploadfiles ) ) {
// look only for uploded files
if ( $uploadfiles['error'] == 0 ) {
$filetmp = $uploadfiles['tmp_name'];
//clean filename
$filename = learndash_clean_filename( $uploadfiles['name'] );
//extract extension
if ( ! function_exists( 'wp_get_current_user' ) ) {
include ABSPATH . 'wp-includes/pluggable.php';
}
//current user
$user = get_current_user_id();
// get file info
// @fixme: wp checks the file extension....
$filetype = wp_check_filetype( basename( $filename ), null );
if ( ( empty( $filetype ) ) || ( empty( $filetype['ext'] ) ) || ( empty( $filetype['type'] ) ) ) {
wp_send_json_error( esc_html__( 'Invalid essay uploaded file type.', 'learndash' ) );
die();
}
//$filetitle = preg_replace( '/\.[^.]+$/', '', basename( $filename ) );
$filetitle = pathinfo( $filename, PATHINFO_FILENAME );
$filename = sprintf( 'question_%d_%s.%s', $question_id, $filetitle, $filetype['ext'] );
$filename = apply_filters( 'learndash_essay_upload_filename', $filename, $question_id, $filetitle, $filetype['ext'] );
$upload_dir = wp_upload_dir();
$upload_dir_base = str_replace( '\\', '/', $upload_dir['basedir'] );
$upload_url_base = $upload_dir['baseurl'];
$upload_dir_path = $upload_dir_base . apply_filters( 'learndash_essay_upload_dirbase', '/essays', $filename, $upload_dir );
$upload_url_path = $upload_url_base . apply_filters( 'learndash_essay_upload_urlbase', '/essays/', $filename, $upload_dir );
if ( ! file_exists( $upload_dir_path ) ) {
if ( is_writable( dirname( $upload_dir_path ) ) ) {
wp_mkdir_p( $upload_dir_path );
} else {
die( esc_html__( 'Unable to write to UPLOADS directory. Is this directory writable by the server?', 'learndash' ) );
return;
}
}
// Add an index.php file to prevent directory browesing
$_index = trailingslashit( $upload_dir_path ) . 'index.php';
if ( !file_exists( $_index ) ) {
file_put_contents ( $_index , '//LearnDash is THE Best LMS' );
}
/**
* Check if the filename already exist in the directory and rename the
* file if necessary
*/
$i = 0;
while ( file_exists( $upload_dir_path . '/' . $filename ) ) {
$i++;
$filename = sprintf( 'question_%d_%s_%d.%s', $question_id, $filetitle, $i, $filetype['ext'] );
$filename = apply_filters( 'learndash_essay_upload_filename_dup', $filename, $question_id, $filetitle, $i, $filetype['ext'] );
}
$filedest = $upload_dir_path . '/' . $filename;
$destination = $upload_url_path . $filename;
/**
* Check write permissions
*/
if ( ! is_writeable( $upload_dir_path ) ) {
wp_send_json_error( esc_html__( 'Unable to write to directory. Is this directory writable by the server?', 'learndash' ) );
die();
}
/**
* Save temporary file to uploads dir
*/
if ( ! @move_uploaded_file( $filetmp, $filedest ) ) {
wp_send_json_error( "Error, the file $filetmp could not moved to : $filedest " );
die();
}
$file_desc = array();
$file_desc['filename'] = $filename;
$file_desc['filelink'] = $destination;
return $file_desc;
}
}
}
/**
* Handle approval of essay in bulk
*
* @since 2.3
*/
function learndash_essay_bulk_actions_approve() {
if ( ( ( isset( $_REQUEST['post'] ) ) && ( ! empty( $_REQUEST['post'] ) ) && (is_array( $_REQUEST['post'] ) ) ) && ( ( isset( $_REQUEST['post_type'] ) ) && ( $_REQUEST['post_type'] == 'sfwd-essays' ) ) ) {
$action = '';
if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
$action = esc_attr( $_REQUEST['action'] );
else if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
$action = esc_attr( $_REQUEST['action2'] );
else if ( ( isset( $_REQUEST['ld_action'] ) ) && ( $_REQUEST['ld_action'] == 'approve_essay') )
$action = 'approve_essay';
if ( $action == 'approve_essay' ) {
if ( ( isset( $_REQUEST['post'] ) ) && ( !empty( $_REQUEST['post'] ) ) ) {
if ( !is_array( $_REQUEST['post'] ) )
$essays = array($_REQUEST['post']);
else
$essays = $_REQUEST['post'];
foreach( $essays as $essay_id ) {
if ( ( !isset( $_REQUEST['essay_points'][$essay_id] ) ) || ( $_REQUEST['essay_points'][$essay_id] == '' ) )
continue;
// get the new assigned points.
$submitted_essay['points_awarded'] = intval( $_REQUEST['essay_points'][$essay_id] );
$essay_post = get_post( $essay_id );
if ( ( !empty( $essay_post ) ) && ( $essay_post instanceof WP_Post ) && ( $essay_post->post_type == 'sfwd-essays' ) ) {
if ( $essay_post->post_status != 'graded' )
$quiz_score_difference = 1;
// First we update the essat post with the new post_status
$essay_post->post_status = 'graded';
wp_update_post( $essay_post );
$user_id = $essay_post->post_author;
$quiz_id = get_post_meta( $essay_post->ID, 'quiz_id', true );
$question_id = get_post_meta( $essay_post->ID, 'question_id', true );
// Stole the following section ot code from learndash_save_essay_status_metabox_data();
$submitted_essay_data = learndash_get_submitted_essay_data( $quiz_id, $question_id, $essay_post );
if ( isset( $submitted_essay_data['points_awarded'] ) )
$original_points_awarded = intval( $submitted_essay_data['points_awarded'] );
else
$original_points_awarded = 0;
$submitted_essay_data['status'] = 'graded';
// get the new assigned points.
$submitted_essay_data['points_awarded'] = intval( $_REQUEST['essay_points'][$essay_id] );
/**
* Filter essay status data
*/
$submitted_essay_data = apply_filters( 'learndash_essay_status_data', $submitted_essay_data );
learndash_update_submitted_essay_data( $quiz_id, $question_id, $essay_post, $submitted_essay_data );
if ( ! is_null( $original_points_awarded ) && ! is_null( $submitted_essay_data['points_awarded'] ) ) {
if ( $submitted_essay_data['points_awarded'] > $original_points_awarded ) {
$points_awarded_difference = intval( $submitted_essay_data['points_awarded'] ) - intval( $original_points_awarded );
} else {
$points_awarded_difference = ( intval( $original_points_awarded ) - intval( $submitted_essay_data['points_awarded'] ) ) * -1;
}
$updated_scoring_data = array(
'updated_question_score' => $submitted_essay_data['points_awarded'],
'points_awarded_difference' => $points_awarded_difference,
'score_difference' => $quiz_score_difference
);
/**
* Filter updated scoring data
*/
$updated_scoring = apply_filters( 'learndash_updated_essay_scoring', $updated_scoring_data );
learndash_update_quiz_data( $quiz_id, $question_id, $updated_scoring_data, $essay_post );
/**
* Perform action after all the quiz data is updated
*/
do_action( 'learndash_essay_all_quiz_data_updated', $quiz_id, $question_id, $updated_scoring_data, $essay_post );
}
}
}
}
}
}
}
add_action( 'load-edit.php', 'learndash_essay_bulk_actions_approve' );
/**
* Delete uploaded file when essay post is deleted
*
* @since 2.5.0
*
* @param int $post_id
*/
function learndash_before_delete_essay( $post_id ) {
if ( ( !empty( $post_id ) ) && ( 'sfwd-essays' == get_post_type( $post_id ) ) ) {
$file_path = get_post_meta( $post_id, 'upload', true );
if ( !empty( $file_path ) ) {
$file_path = basename( $file_path );
$url_link_arr = wp_upload_dir();
$file_path = trailingslashit( str_replace('\\', '/', $url_link_arr['basedir'] ) ) . 'essays/' . basename( $file_path );
if ( file_exists( $file_path ) ) {
unlink( $file_path );
}
}
}
}
add_action( 'before_delete_post', 'learndash_before_delete_essay' );
/**
* Update the Essays post meta with a reference to the quiz attempt user meta.
*
* @since 3.1
* @param array $quizdata Collection of quiz attempt data.
* @param object $user WP User object.
*/
function learndash_quiz_submitted_update_essay( $quizdata = array(), $user ) {
if ( ( isset( $quizdata['time'] ) ) && ( ! empty( $quizdata['time'] ) ) ) {
if ( ( isset( $quizdata['has_graded'] ) ) && ( true === $quizdata['has_graded'] ) ) {
if ( ( isset( $quizdata['graded'] ) ) && ( ! empty( $quizdata['graded'] ) ) ) {
foreach( $quizdata['graded'] as $question_id => $graded_data ) {
if ( isset( $graded_data['post_id'] ) ) {
$essay_post_id = absint( $graded_data['post_id'] );
if ( ! empty( $essay_post_id ) ) {
$quiz_time = get_post_meta( $essay_post_id, 'quiz_time', true );
if ( ! $quiz_time ) {
update_post_meta( $essay_post_id, 'quiz_time', $quizdata['time'] );
}
}
}
}
}
}
}
}
add_action( 'learndash_quiz_submitted', 'learndash_quiz_submitted_update_essay', 1, 2 ); ld-quiz-metaboxes.php 0000666 00000002515 15214240426 0010636 0 ustar 00 id ) {
return;
}
add_meta_box(
'sfwd-quiz-questions',
sprintf( '%s', \LearnDash_Custom_Label::get_label( 'questions' ) ),
'LearnDash\Quiz\Metaboxes\meta_box_questions_callback',
null,
'side'
);
/*
add_meta_box(
'learndash_admin_quiz_navigation',
sprintf(
// translators: placeholders: Quiz, Questions.
esc_html_x( '%1$s %2$s', 'placeholders: Quiz, Questions', 'learndash' ),
\LearnDash_Custom_Label::get_label( 'quiz' ), \LearnDash_Custom_Label::get_label( 'questions' )
),
'learndash_quiz_navigation_admin_box_content',
null,
'side'
);
*/
}
add_action( 'add_meta_boxes_sfwd-quiz', 'LearnDash\Quiz\Metaboxes\add_meta_boxes' );
add_action( 'learndash_add_meta_boxes', 'LearnDash\Quiz\Metaboxes\add_meta_boxes' );
/**
* Callback to render questions metabox.
*
* @return void
*/
function meta_box_questions_callback() {
?>
$shortcode_atts ) {
if ( in_array( $shortcode_tag, array('LDAdvQuiz', 'ld_quiz' ) ) ) {
if ( ( isset( $shortcode_atts['quiz_post_id'] ) ) && ( ! empty( $shortcode_atts['quiz_post_id'] ) ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $shortcode_atts['quiz_post_id'] );
return $quiz_post_ids[ $quiz_pro_id ];
} elseif ( ( isset( $shortcode_atts['quiz_id'] ) ) && ( ! empty( $shortcode_atts['quiz_id'] ) ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $shortcode_atts['quiz_id'] );
return $quiz_post_ids[ $quiz_pro_id ];
} elseif ( ( isset( $shortcode_atts['quiz'] ) ) && ( ! empty( $shortcode_atts['quiz'] ) ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $shortcode_atts['quiz'] );
return $quiz_post_ids[ $quiz_pro_id ];
}
}
}
}
// Before we run all the queries we check the global $post and see if we are showing a Quiz Post.
$queried_object = get_queried_object();
if ( ( is_a( $queried_object, 'WP_Post' ) ) && ( learndash_get_post_type_slug( 'quiz' ) === $queried_object->post_type ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $queried_object->ID );
return $quiz_post_ids[ $quiz_pro_id ];
}
/*
$post_id = get_the_ID();
if ( ! empty( $post_id ) ) {
$quiz_post = get_post( $post_id );
if ( ( $quiz_post instanceof WP_Post ) && ( $quiz_post->post_type == 'sfwd-quiz' ) ) {
//$quiz_post_id = $quiz_post->ID;
$quiz_pro_id_tmp = learndash_get_setting( $quiz_post->ID, 'quiz_pro' );
if ( ( $quiz_pro_id_tmp ) && ( absint( $quiz_pro_id_tmp ) === $quiz_pro_id ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $quiz_pro_id_tmp );
return $quiz_post_ids[ $quiz_pro_id ];
}
}
}
*/
$sql_str = $wpdb->prepare( "SELECT post_id FROM " . $wpdb->postmeta . " as postmeta INNER JOIN " . $wpdb->posts . " as posts ON posts.ID=postmeta.post_id
WHERE posts.post_type = %s AND posts.post_status = %s AND postmeta.meta_key = %s", 'sfwd-quiz', 'publish', 'quiz_pro_id_' . absint( $quiz_pro_id ) );
$quiz_post_id = $wpdb->get_var( $sql_str );
if ( ! empty( $quiz_post_id ) ) {
$quiz_post_ids[ $quiz_pro_id ] = absint( $quiz_post_id );
return $quiz_post_ids[ $quiz_pro_id ];
}
$sql_str = $wpdb->prepare( "SELECT post_id FROM " . $wpdb->postmeta . " as postmeta INNER JOIN " . $wpdb->posts . " as posts ON posts.ID=postmeta.post_id
WHERE posts.post_type = %s AND posts.post_status = %s AND meta_key = %s AND meta_value = %d", 'sfwd-quiz', 'publish', 'quiz_pro_id', absint( $quiz_pro_id ));
$quiz_post_id = $wpdb->get_var( $sql_str );
if ( ! empty( $quiz_post_id ) ) {
update_post_meta( absint( $quiz_post_id ), 'quiz_pro_id_' . absint( $quiz_pro_id ), absint( $quiz_pro_id ) );
$quiz_post_ids[ $quiz_pro_id ] = absint( $quiz_post_id );
return $quiz_post_ids[ $quiz_pro_id ];
}
// Because we seem to have a mix of int and string values when these are serialized the format to look for end up being somewhat kludge-y.
$quiz_pro_id_str = sprintf( '%s', absint( $quiz_pro_id ) );
$quiz_pro_id_len = strlen( $quiz_pro_id_str );
$like_i = 'sfwd-quiz_quiz_pro";i:' . absint( $quiz_pro_id ) . ';';
$like_s = '"sfwd-quiz_quiz_pro";s:' . $quiz_pro_id_len . ':"' . $quiz_pro_id_str . '"';
// Using REGEX because it is slightly faster then OR on text fields pattern search.
$sql_str = $wpdb->prepare( "SELECT post_id FROM " . $wpdb->postmeta . " as postmeta INNER JOIN " . $wpdb->posts . " as posts ON posts.ID=postmeta.post_id WHERE posts.post_type = %s AND posts.post_status = %s AND postmeta.meta_key=%s AND postmeta.meta_value REGEXP '" . $like_i . "|" . $like_s . "'", 'sfwd-quiz', 'publish', '_sfwd-quiz' );
$quiz_post_id = $wpdb->get_var( $sql_str );
if ( ! empty( $quiz_post_id ) ) {
$quiz_post_id = absint( $quiz_post_id );
update_post_meta( $quiz_post_id, 'quiz_pro_id_' . absint( $quiz_pro_id ), absint( $quiz_pro_id ) );
update_post_meta( $quiz_post_id, 'quiz_pro_id', absint( $quiz_pro_id ) );
$quiz_post_ids[ $quiz_pro_id ] = $quiz_post_id;
return $quiz_post_ids[ $quiz_pro_id ];
}
}
}
/**
* Get a Question Post ID from the Proquiz ID
*
* @since 2.6.0
*
* @param int $question_pro_id ProQuiz Question id.
* @return int quiz post id
*/
function learndash_get_question_post_by_pro_id( $question_pro_id = 0 ) {
global $wpdb;
if ( empty( $question_pro_id ) ) {
return;
}
$question_pro_args = array(
'post_type' => learndash_get_post_type_slug( 'question' ),
'posts_per_page' => 1,
'post_status' => 'any',
'fields' => 'ids',
'meta_query' => array(
array(
'key' => 'question_pro_id',
'value' => $question_pro_id,
'compare' => '=',
'type' => 'NUMERIC',
),
),
);
$question_pro_query = new WP_Query( $question_pro_args );
if ( ( is_a( $question_pro_query, 'WP_Query' ) ) && ( property_exists( $question_pro_query, 'posts' ) ) ) {
if ( ( ! empty( $question_pro_query->posts ) ) && ( isset( $question_pro_query->posts[0] ) ) ) {
return $question_pro_query->posts[0];
}
}
}
/**
* Action hook called when a Question (sfwd-question) is moved to trash or untrashed.
*
* @since 2.6.0
*
* @param string $new_status New post_status value.
* @param string $old_status Old post_status value.
* @param Object $post WP_Post object instance.
*/
function learndash_transition_quiz_question_post_status( $new_status, $old_status, $post ) {
global $wpdb;
if ( $new_status !== $old_status ) {
if ( ( ! empty( $post ) ) && ( is_a( $post, 'WP_Post' ) ) && ( in_array( $post->post_type, array( 'sfwd-question' ) ) ) === true ) {
$sql_str = "SELECT meta_value FROM " . $wpdb->postmeta . " WHERE post_id = " . $post->ID . " AND (meta_key = 'quiz_id' OR meta_key LIKE 'ld_quiz_%')";
$quiz_ids = $wpdb->get_col( $sql_str );
if ( ! empty( $quiz_ids ) ) {
$quiz_ids = array_unique( $quiz_ids );
foreach ( $quiz_ids as $quiz_id ) {
learndash_set_quiz_questions_dirty( $quiz_id );
}
}
}
}
}
add_action( 'transition_post_status', 'learndash_transition_quiz_question_post_status', 10, 3 );
/**
* Interface function to set the Quiz 'dirty' flag for questions.
* This 'dirty' flag is used to trigger the Quiz logic to relod the questions
* via queries instead of using the stored questions post meta. This generally
* means something changed with the questions.
*
* @since 2.6.0
* @param integer $quiz_id Quiz ID to change dirty flag.
*/
function learndash_set_quiz_questions_dirty( $quiz_id = 0 ) {
if ( ! empty( $quiz_id ) ) {
$quiz_questions_object = LDLMS_Factory_Post::quiz_questions( absint( $quiz_id ) );
if ( is_a( $quiz_questions_object, 'LDLMS_Quiz_Questions' ) ) {
$quiz_questions_object->set_questions_dirty();
}
}
}
/**
* For a given Question post gather all the quiz posts and set each as
* questions dirty.
*
* @since 2.6.0
* @param integer $question_post_id Question Post ID.
*/
function learndash_set_question_quizzes_dirty( $question_post_id = 0 ) {
$question_post_id = absint( $question_post_id );
if ( ! empty( $question_post_id ) ) {
$question_quiz_ids = learndash_get_quizzes_for_question( $question_post_id, true );
if ( ! empty( $question_quiz_ids ) ) {
foreach ( $question_quiz_ids as $question_quiz_id => $quiz_title ) {
learndash_set_quiz_questions_dirty( $question_quiz_id );
}
}
}
}
/**
* Adds a WPProQuiz question to mirror a Question post (sfwd-question).
*
* @since 2.6.0
* @param integer $question_pro_id Post ID of Question (sfwd-question).
* @param array $post_data Post Data containing post_title and post_content.
* @return integer new question pro id.
*/
function learndash_update_pro_question( $question_pro_id = 0, $post_data = array() ) {
$question_pro_id = absint( $question_pro_id );
$question_mapper = new WpProQuiz_Model_QuestionMapper();
if ( isset( $post_data['action'] ) ) {
switch ( $post_data['action'] ) {
case 'editpost':
$proquiz_controller_question = new WpProQuiz_Controller_Question();
$question_model = $proquiz_controller_question->getPostQuestionModel( 0, $question_pro_id );
break;
case 'new_step':
$proquiz_controller_question = new WpProQuiz_Controller_Question();
$question_model = $proquiz_controller_question->getPostQuestionModel( 0, $question_pro_id );
break;
case 'edit_title':
$question_model = $question_mapper->fetchById( absint( $question_pro_id ) );
break;
default:
break;
}
}
if ( ( isset( $question_model ) ) && ( is_a( $question_model, 'WpProQuiz_Model_Question' ) ) ) {
if ( ( isset( $post_data['post_type'] ) ) && ( $post_data['post_type'] === learndash_get_post_type_slug( 'question' ) ) ) {
if ( isset( $post_data['post_title'] ) ) {
$question_model->setTitle( $post_data['post_title'] );
}
if ( isset( $post_data['post_content'] ) ) {
$question_model->setQuestion( $post_data['post_content'] );
}
if ( ( isset( $post_data['post_ID'] ) ) && ( ! empty( $post_data['post_ID'] ) ) ) {
$quiz_post_id = learndash_get_setting( $post_data['post_ID'], 'quiz' );
if ( ! empty( $quiz_post_id ) ) {
$quiz_post_id = absint( $quiz_post_id );
$quiz_pro_id = learndash_get_setting( $quiz_post_id, 'quiz_pro' );
if ( ! empty( $quiz_pro_id ) ) {
$question_model->setQuizId( $quiz_pro_id );
}
}
}
}
$question = $question_mapper->save( $question_model, true );
learndash_update_question_template( $question, $post_data );
// After the save we check the question ID in case WPProQuiz changed it.
$question_pro_id = $question->getId();
return $question_pro_id;
}
}
/**
* Handle the Question Save Template logic.
*
* @since 2.6.0
* @param object $question WpProQuiz_Model_Question instance.
* @param array $post_data $_POST data to process the templated related fields.
* @return mixed on success WpProQuiz_Model_Template instance.
*/
function learndash_update_question_template( $question = null, $post_data = array() ) {
if ( ( ! empty( $post_data ) ) && ( ! empty( $question ) ) ) {
$template_mapper = new WpProQuiz_Model_TemplateMapper();
if ( ( isset( $post_data['templateName'] ) ) && ( ! empty( $post_data['templateName'] ) ) ) {
$template = new WpProQuiz_Model_Template();
$template->setType( WpProQuiz_Model_Template::TEMPLATE_TYPE_QUESTION );
$template->setName( trim( $post_data['templateName'] ) );
} else if ( ( isset( $post_data['templateSaveList'] ) ) && ( ! empty( $post_data['templateSaveList'] ) ) ) {
$template = $template_mapper->fetchById( absint( $post_data['templateSaveList'] ), false );
}
if ( ( isset( $template ) ) && ( is_a( $template, 'WpProQuiz_Model_Template' ) ) ) {
$template->setData( array(
'question' => $question,
) );
return $template_mapper->save( $template );
}
}
}
/**
* Gets an array of Quiz IDS where the question is used.
*
* @since 2.6.0
* @param integer $question_post_id Question Post ID.
* @param boolean $return_flat_array Default is false and will return primary and secondary sub-array sets.
* @return array of Quiz post IDs.
*/
function learndash_get_quizzes_for_question( $question_post_id = 0, $return_flat_array = false ) {
global $wpdb;
$quiz_ids = array();
if ( true !== $return_flat_array ) {
$course_ids['primary'] = array();
$course_ids['secondary'] = array();
}
if ( ! empty( $question_post_id ) ) {
$sql_str = $wpdb->prepare( "SELECT postmeta.meta_value as quiz_id, posts.post_title as quiz_title FROM " . $wpdb->postmeta . " AS postmeta
INNER JOIN " . $wpdb->posts . " AS posts ON postmeta.meta_value = posts.ID WHERE postmeta.post_id = " . $question_post_id . " AND postmeta.meta_key LIKE %s ORDER BY quiz_title ASC", 'quiz_id' );
$quiz_ids_primary = $wpdb->get_results( $sql_str );
if ( ! empty( $quiz_ids_primary ) ) {
foreach ( $quiz_ids_primary as $quiz_set ) {
if ( true === $return_flat_array ) {
$quiz_ids[ $quiz_set->quiz_id ] = $quiz_set->quiz_title;
} else {
$quiz_ids['primary'][ $quiz_set->quiz_id ] = $quiz_set->quiz_title;
}
}
}
$sql_str = "SELECT postmeta.meta_value as quiz_id, posts.post_title as quiz_title FROM " . $wpdb->postmeta . " AS postmeta
INNER JOIN " . $wpdb->posts . " AS posts ON postmeta.meta_value = posts.ID WHERE postmeta.post_id = " . $question_post_id . " AND postmeta.meta_key LIKE 'ld_quiz_%' ORDER BY quiz_title ASC" ;
$quiz_ids_secondary = $wpdb->get_results( $sql_str );
if ( ! empty( $quiz_ids_secondary ) ) {
foreach ( $quiz_ids_secondary as $quiz_set ) {
if ( true === $return_flat_array ) {
if ( ! isset( $quiz_ids[ $quiz_set->quiz_id ] ) ) {
$quiz_ids[ $quiz_set->quiz_id ] = $quiz_set->quiz_title;
}
} else {
if ( ( ! isset( $quiz_ids['primary'][ $quiz_set->quiz_id ] ) ) && ( ! isset( $quiz_ids['secondary'][ $quiz_set->quiz_id ] ) ) ) {
$quiz_ids['secondary'][ $quiz_set->quiz_id ] = $quiz_set->quiz_title;
}
}
}
}
return $quiz_ids;
}
}
/**
* Determine the Quiz ID based on the global post being viewed.
*
* @since 2.6.0
* @param integer $id Post ID being viewed.
* @return integer The found quiz ID or false.
*/
function learndash_get_quiz_id( $id = null ) {
global $post;
if ( is_object( $id ) && $id->ID ) {
$p = $id;
$id = $p->ID;
} elseif ( is_numeric( $id ) ) {
$p = get_post( $id );
}
if ( empty( $id ) ) {
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
//return false;
} else {
if ( is_admin() ) {
global $parent_file, $post_type, $pagenow;
if ( ( ! in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) || ( ! in_array( $post_type, array( 'sfwd-question' ) ) ) ) {
return false;
}
} else if ( ! is_single() || is_home() ) {
return false;
}
}
if ( ( $post ) && ( $post instanceof WP_Post ) ) {
$id = $post->ID;
$p = $post;
} else {
return false;
}
}
if ( empty( $p->ID ) ) {
return 0;
}
if ( learndash_get_post_type_slug( 'quiz' ) === $p->post_type ) {
return $p->ID;
}
if ( ( isset( $_GET['quiz_id'] ) ) && ( ! empty( $_GET['quiz_id'] ) ) ) {
return absint( $_GET['quiz_id'] );
} elseif ( ( isset( $_GET['quiz'] ) ) && ( ! empty( $_GET['quiz'] ) ) ) {
return absint( $_GET['quiz'] );
} elseif ( ( isset( $_POST['quiz_id'] ) ) && ( ! empty( $_POST['quiz_id'] ) ) ) {
return absint( $_POST['quiz_id'] );
} else if ( ( isset( $_POST['quiz'] ) ) && ( ! empty( $_POST['quiz'] ) ) ) {
return intval( $_POST['quiz'] );
} else if ( ( isset( $_GET['post'] ) ) && ( ! empty( $_GET['post'] ) ) ) {
if ( learndash_get_post_type_slug( 'quiz' ) === get_post_type( intval( $_GET['post'] ) ) ) {
return intval( $_GET['post'] );
}
}
return (int) get_post_meta( $id, 'quiz_id', true );
}
/**
* Add content to quiz navigation meta box for admin
*
* @since 2.6.0
*/
function learndash_quiz_navigation_admin_box_content() {
global $typenow;
$quiz_id = 0;
$current_post = false;
if ( ( isset( $_GET['post'] ) ) && ( ! empty( $_GET['post'] ) ) ) {
$quiz_id = learndash_get_quiz_id( absint( $_GET['post'] ) );
$current_post = get_post( intval( $_GET['post'] ) );
}
if ( ( empty( $quiz_id ) ) && ( isset( $_GET['quiz_id'] ) ) ) {
$quiz_id = absint( $_GET['quiz_id'] );
}
if ( ! empty( $quiz_id ) ) {
$instance = array();
$instance['show_widget_wrapper'] = true;
$instance['quiz_id'] = $quiz_id;
$instance['current_question_id'] = 0;
$instance['current_type'] = $typenow;
$question_query_args = array();
$question_query_args['pagination'] = 'true';
$question_query_args['paged'] = 1;
if ( ( is_a( $current_post, 'WP_Post' ) ) && ( in_array( $current_post->post_type, array( 'sfwd-quiz', 'sfwd-question' ) ) ) ) {
if ( in_array( $current_post->post_type, array( 'sfwd-question' ) ) ) {
$instance['current_question_id'] = $current_post->ID;
}
}
learndash_quiz_navigation_admin( $quiz_id, $instance, $question_query_args );
if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Quizzes_Builder', 'shared_questions' ) == 'yes' ) {
learndash_quiz_switcher_admin( $quiz_id );
}
} else {
echo sprintf(
// translators: placeholders: Questions.
esc_html_x( 'No associated %s', 'placeholder: Questions', 'learndash' ),
LearnDash_Custom_Label::get_label( 'questions' )
);
echo sprintf(
'',
esc_attr( $quiz_id )
);
}
}
/**
* Utility function to get the questions associated with a Quiz
*
* @since 2.6.0
* @param integer $quiz_id The Quiz Post ID.
* @return array of quiz question (sfwd-question) post ids.
*/
function learndash_get_quiz_questions( $quiz_id = 0 ) {
if ( ! empty( $quiz_id ) ) {
$ld_quiz_questions_object = LDLMS_Factory_Post::quiz_questions( absint( $quiz_id ) );
if ( $ld_quiz_questions_object ) {
$ld_quiz_questions = $ld_quiz_questions_object->get_questions();
return $ld_quiz_questions;
}
}
}
/**
* Outputs quiz navigation admin template for widget
*
* @since 2.6.0
*
* @param integer $quiz_id Quiz Post ID.
* @param array $instance Widget instance array.
* @param array $question_query_args array of query options for pagnination etc.
*
* @return string quiz navigation output
*/
function learndash_quiz_navigation_admin( $quiz_id = 0, $instance = array(), $question_query_args = array() ) {
if ( empty( $quiz_id ) ) {
return;
}
$quiz = get_post( absint( $quiz_id ) );
if ( ( ! $quiz ) || ( ! is_a( $quiz, 'WP_Post' ) ) || ( learndash_get_post_type_slug( 'quiz' ) !== $quiz->post_type ) ) {
return;
}
if ( is_user_logged_in() ) {
$user_id = get_current_user_id();
} else {
$user_id = 0;
}
$instance['nonce'] = wp_create_nonce( 'ld_quiz_navigation_admin_pager_nonce_' . $quiz->ID . '_' . get_current_user_id() );
$quiz_navigation_admin_pager = array();
global $quiz_navigation_admin_pager;
$question_start_idx = 0;
$question_list = learndash_get_quiz_questions( $quiz_id );
if ( ! empty( $question_list ) ) {
//$course_lessons_per_page = learndash_get_course_lessons_per_page( $quiz_id );
$quiz_questions_per_page = LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'question_num' );
if ( ( $quiz_questions_per_page > 0 ) && ( count( $question_list ) > $quiz_questions_per_page ) ) {
$quiz_navigation_admin_pager['per_page'] = absint( $quiz_questions_per_page );
$quiz_navigation_admin_pager['total_items'] = count( $question_list );
$questions_page_chunks = array_chunk( $question_list, $quiz_navigation_admin_pager['per_page'], true );
$quiz_navigation_admin_pager['total_pages'] = count( $questions_page_chunks );
$quiz_navigation_admin_pager['paged'] = 1;
if ( ( isset( $_POST['paged'] ) ) && ( ! empty( $_POST['paged'] ) ) ) {
$quiz_navigation_admin_pager['paged'] = absint( $_POST['paged'] );
} else {
foreach( $questions_page_chunks as $paged_idx => $paged_set ) {
if ( isset( $paged_set[ $instance['current_question_id'] ] ) ) {
$quiz_navigation_admin_pager['paged'] = $paged_idx + 1;
break;
}
}
}
$chunks_paged = $quiz_navigation_admin_pager['paged'] - 1;
if ( isset( $questions_page_chunks[ $chunks_paged ] ) ) {
$question_list = $questions_page_chunks[ $chunks_paged ];
} else {
$question_list = $questions_page_chunks[0];
}
}
} else {
echo sprintf(
// translators: placeholders: Questions.
esc_html_x( 'No associated %s', 'placeholder: Questions', 'learndash' ),
LearnDash_Custom_Label::get_label( 'questions' )
);
}
SFWD_LMS::get_template(
'quiz_navigation_admin',
array(
'user_id' => $user_id,
'quiz_id' => $quiz_id,
'widget' => $instance,
'questions_list' => $question_list,
),
true
);
}
/**
* Show the Quiz Switcher within the Quiz Questions Admin metabox.
*
* @since 2.6.0
* @param integer $quiz_id Quiz Post ID.
*/
function learndash_quiz_switcher_admin( $quiz_id ) {
$template_file = SFWD_LMS::get_template(
'quiz_navigation_switcher_admin',
array(),
null,
true
);
if ( ! empty( $template_file ) ) {
include $template_file;
}
}
/**
* Quiz Questions Navigation AJAX Pager handler function
*
* @since 2.5.4
*/
function learndash_wp_ajax_ld_quiz_navigation_admin_pager() {
$reply_data = array();
if ( ( isset( $_POST['paged'] ) ) && ( ! empty( $_POST['paged'] ) ) ) {
$paged = intval( $_POST['paged'] );
} else {
$paged = 1;
}
if ( ( isset( $_POST['widget_data'] ) ) && ( ! empty( $_POST['widget_data'] ) ) ) {
$widget_data = $_POST['widget_data'];
} else {
$widget_data = array();
}
if ( ( isset( $widget_data['quiz_id'] ) ) && ( ! empty( $widget_data['quiz_id'] ) ) ) {
$quiz_id = intval( $widget_data['quiz_id'] );
} else {
$quiz_id = 0;
}
if ( ( ! empty( $quiz_id ) ) && ( ! empty( $widget_data ) ) ) {
if ( ( isset( $_POST['widget_data']['nonce'] ) ) && ( ! empty( $_POST['widget_data']['nonce'] ) ) && ( wp_verify_nonce( $_POST['widget_data']['nonce'], 'ld_quiz_navigation_admin_pager_nonce_' . $quiz_id . '_' . get_current_user_id() ) ) ) {
$questions_query_args = array();
//$course_lessons_per_page = learndash_get_course_lessons_per_page( $course_id );
//if ( $course_lessons_per_page > 0 ) {
$questions_query_args['pagination'] = 'true';
$questions_query_args['paged'] = $paged;
//}
$widget_data['show_widget_wrapper'] = false;
$level = ob_get_level();
ob_start();
learndash_quiz_navigation_admin( $quiz_id, $widget_data, $questions_query_args );
$reply_data['content'] = learndash_ob_get_clean( $level );
}
}
echo json_encode( $reply_data );
die();
}
add_action( 'wp_ajax_ld_quiz_navigation_admin_pager', 'learndash_wp_ajax_ld_quiz_navigation_admin_pager' );
/**
* This function will copy the WPProQuiz Question Category to the LearnDadh Question taxonomy
*
* @since 2.6.0
* @param integer $question_post_id WP_Post Question ID.
* @param integer $question_pro_id WpProQuiz_Model_Question object or ID.
*/
function learndash_proquiz_sync_question_fields( $question_post_id = 0, $question_pro_id = 0 ) {
if ( ( empty( $question_post_id ) ) || ( empty( $question_pro_id ) ) ) {
return;
}
if ( is_a( $question_pro_id, 'WpProQuiz_Model_Question' ) ) {
$question_pro = $question_pro_id;
} else {
$question_pro_mapper = new WpProQuiz_Model_QuestionMapper();
$question_pro = $question_pro_mapper->fetch( absint( $question_pro_id ) );
}
if ( is_a( $question_pro, 'WpProQuiz_Model_Question' ) ) {
update_post_meta( $question_post_id, 'question_points', intval( $question_pro->getPoints() ) );
update_post_meta( $question_post_id, 'question_type', $question_pro->getAnswerType() );
update_post_meta( $question_post_id, 'question_pro_id', intval( $question_pro->getId() ) );
update_post_meta( $question_post_id, 'question_pro_category', intval( $question_pro->getCategoryId() ) );
// Not sure why this is here.
/*
$update_post = array(
'ID' => $question_post_id,
'post_title' => $question_pro->getTitle(),
'post_content' => $question_pro->getQuestion(),
'menu_order' => absint( $question_pro->getSort() ),
);
wp_update_post( $update_post );
*/
/*
$quiz_post_ids = learndash_get_quiz_post_ids( $question_pro->getQuizId() );
if ( ! empty( $quiz_post_ids ) ) {
foreach ( $quiz_post_ids as $idx => $quiz_post_id ) {
if ( 0 === $idx ) {
learndash_update_setting( $question_post_id, 'quiz', absint( $quiz_post_id ) );
}
//if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Quizzes_Builder', 'shared_questions' ) === 'yes' ) {
add_post_meta( $question_post_id, 'ld_quiz_id', intval( $quiz_post_id ), true );
//}
}
}
*/
}
}
/**
* This function will copy the WPProQuiz Question Category to the LearnDadh Question taxonomy
*
* @since 2.6.0
* @param integer $question_post_id WP_Post Question ID.
* @param integer $question_pro_id WpProQuiz_Model_Question object or ID.
* @return object WP_Term object.
*/
function learndash_proquiz_sync_question_category( $question_post_id = 0, $question_pro_id = 0 ) {
if ( ( empty( $question_post_id ) ) || ( empty( $question_pro_id ) ) ) {
return;
}
if ( is_a( $question_pro_id, 'WpProQuiz_Model_Question' ) ) {
$question_pro = $question_pro_id;
} else {
$question_pro_mapper = new WpProQuiz_Model_QuestionMapper();
$question_pro = $question_pro_mapper->fetch( absint( $question_pro_id ) );
}
if ( is_a( $question_pro, 'WpProQuiz_Model_Question' ) ) {
// Sync the Question category with the LD Question Category.
if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Questions_Taxonomies', 'ld_question_category' ) == 'yes' ) {
$question_pro_category_id = $question_pro->getCategoryId();
$question_pro_category_name = $question_pro->getCategoryName();
if ( ( ! empty( $question_pro_category_id ) ) && ( ! empty( $question_pro_category_name ) ) ) {
$category_query_args = array(
'taxonomy' => array( 'ld_question_category' ),
'hide_empty' => false,
'name' => $question_pro_category_name,
);
$category_terms = get_terms( $category_query_args );
if ( ! is_wp_error( $category_terms ) ) {
if ( ! empty( $category_terms ) ) {
foreach ( $category_terms as $category_term ) {
wp_set_object_terms( $question_post_id, $category_term->term_id, 'ld_question_category' );
}
return $category_terms;
} else {
$new_term = wp_insert_term( $question_pro_category_name, 'ld_question_category' );
if ( isset( $new_term['term_id'] ) ) {
add_term_meta( absint( $new_term['term_id'] ), 'category_pro_id', $question_pro_category_id );
wp_set_object_terms( $question_post_id, intval( $new_term['term_id'] ), 'ld_question_category' );
return $new_term;
}
}
}
}
}
}
}
/**
* Utility function to return all the quiz posts IDs based on the quiz pro id.
* This is similar to the function learndash_get_quiz_id_by_pro_quiz_id() but returns
* an array instead of a single post ID.
*
* @since 2.6.0
* @param integer $quiz_pro_id ID of WPProQuiz Quiz.
* @return array of quiz post IDs.
*/
function learndash_get_quiz_post_ids( $quiz_pro_id = 0 ) {
static $quiz_post_ids = array();
$quiz_pro_id = absint( $quiz_pro_id );
if ( ! empty( $quiz_pro_id ) ) {
if ( ! isset( $quiz_post_ids[ $quiz_pro_id ] ) ) {
$quiz_post_ids[ $quiz_pro_id ] = array();
if ( ! empty( $quiz_pro_id ) ) {
$quiz_query_args = array(
'post_type' => learndash_get_post_type_slug( 'quiz' ),
'posts_per_page' => -1,
'fields' => 'ids',
'orderby' => 'ID',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'quiz_pro_id',
'value' => absint( $quiz_pro_id ),
'compare' => '=',
),
),
);
$quiz_query = new WP_Query( $quiz_query_args );
if ( ( $quiz_query instanceof WP_Query ) && ( property_exists( $quiz_query, 'posts' ) ) ) {
$quiz_post_ids[ $quiz_pro_id ] = array_merge( $quiz_post_ids[ $quiz_pro_id ], $quiz_query->posts );
}
}
}
return $quiz_post_ids[ $quiz_pro_id ];
}
}
/**
* This function retreives the WPProQuiz Question row column by field.
*
* @since 2.6.0
* @param integer $question_pro_id WPProQuiz Question ID.
* @param mixed $fields Array or string of fields to return.
* @return array of field values.
*/
function leandash_get_question_pro_fields( $question_pro_id = 0, $fields = null ) {
$values = array();
if ( ( ! empty( $question_pro_id ) ) && ( ! empty( $fields ) ) ) {
if ( is_string( $fields ) ) {
$fields = explode( ',', $fields );
}
if ( is_array( $fields ) ) {
$fields = array_map( 'trim', $fields );
}
$question_mapper = new WpProQuiz_Model_QuestionMapper();
$question_pro = $question_mapper->fetch( $question_pro_id );
foreach ( $fields as $field ) {
$function = 'get' . str_replace( ' ', '', ucwords( str_replace( '_', ' ', $field ) ) );
if ( method_exists( $question_pro, $function ) ) {
$values[ $field ] = $question_pro->$function();
} else {
$values[ $field ] = null;
}
}
return $values;
}
return $values;
}
/**
* This function retreives the WPProQuiz Quiz row column by field.
*
* @since 2.6.0
* @param integer $question_pro_id WPProQuiz Question ID.
* @param mixed $fields Array or string of fields to return.
* @return array of field values.
*/
function leandash_get_quiz_pro_fields( $quiz_pro_id = 0, $fields = null ) {
$values = array();
if ( ( ! empty( $quiz_pro_id ) ) && ( ! empty( $fields ) ) ) {
if ( is_string( $fields ) ) {
$fields = explode( ',', $fields );
}
if ( is_array( $fields ) ) {
$fields = array_map( 'trim', $fields );
}
$quiz_mapper = new WpProQuiz_Model_QuizMapper();
$quiz_pro = $quiz_mapper->fetch( $quiz_pro_id );
foreach ( $fields as $field ) {
$function = 'get' . str_replace( ' ', '', ucwords( str_replace( '_', ' ', $field ) ) );
if ( method_exists( $quiz_pro, $function ) ) {
$values[ $field ] = $quiz_pro->$function();
} else {
$values[ $field ] = null;
}
}
return $values;
}
return $values;
}
/**
* This function accepts a list of Quiz posts. It is assumed quiz posts
* all share the same ProQuiz Quiz ID. This function will determine which
* is the 'primary' quiz post. If one is not found the first in the array
* will be set as the primary.
*
* @since 2.6.0
* @param integer $quiz_pro_id ProQuiz Quiz ID.
* @param boolean $set_first If true will take first quiz post fount and use as primary.
* @return integer Primary Quiz Post ID.
*/
function learndash_get_quiz_primary_shared( $quiz_pro_id = 0, $set_first = true ) {
static $quiz_primary_post_ids = array();
$quiz_pro_id = absint( $quiz_pro_id );
if ( ! empty( $quiz_pro_id ) ) {
if ( ( ! isset( $quiz_primary_post_ids[ $quiz_pro_id ] ) ) || ( empty( $quiz_primary_post_ids[ $quiz_pro_id ] ) ) ) {
$quiz_primary_post_ids[ $quiz_pro_id ] = 0;
$quiz_post_ids = learndash_get_quiz_post_ids( $quiz_pro_id );
if ( ! empty( $quiz_post_ids ) ) {
$quiz_query_args = array(
'post_type' => learndash_get_post_type_slug( 'quiz' ),
'posts_per_page' => -1,
'fields' => 'ids',
'orderby' => 'ID',
'order' => 'ASC',
'post__in' => $quiz_post_ids,
'meta_query' => array(
array(
'key' => 'quiz_pro_primary_' . $quiz_pro_id,
'compare' => 'EXISTS',
),
),
);
$quiz_query = new WP_Query( $quiz_query_args );
if ( ( is_a( $quiz_query, 'WP_Query' ) ) && ( property_exists( $quiz_query, 'posts' ) ) && ( ! empty( $quiz_query->posts ) ) ) {
$quiz_primary_post_ids[ $quiz_pro_id ] = $quiz_query->posts[0];
if ( count( $quiz_query->posts ) > 1 ) {
foreach ( $quiz_query->posts as $quiz_post_idx => $quiz_post_id ) {
if ( 0 !== $quiz_post_idx ) {
delete_post_meta( $quiz_post_id, 'quiz_pro_primary_' . $quiz_pro_id );
}
}
}
} else {
if ( true === $set_first ) {
$quiz_primary_post_ids[ $quiz_pro_id ] = $quiz_post_ids[0];
update_post_meta( $quiz_primary_post_ids[ $quiz_pro_id ], 'quiz_pro_primary_' . $quiz_pro_id, $quiz_pro_id );
}
}
}
}
return $quiz_primary_post_ids[ $quiz_pro_id ];
}
}
function learndash_quiz_result_message_sort( $messages = array() ) {
$sorted = array();
if ( ( isset( $messages ) ) && ( ! empty( $messages ) ) ) {
$activ_bypass = false;
if ( ! isset( $messages['activ'] ) ) {
$activ_bypass = true;
}
for ( $i = 0; $i < LEARNDASH_QUIZ_RESULT_MESSAGE_MAX; $i++ ) {
if ( true === $activ_bypass ) {
$activ = 1;
} else {
$activ = null;
if ( isset( $messages['activ'][$i] ) ) {
$activ = absint( $messages['activ'][$i] );
}
}
$prozent = null;
if ( isset( $messages['prozent'][$i] ) ) {
$prozent = (float)str_replace(',', '.', $messages['prozent'][$i] );
}
$text = null;
if ( isset( $messages['text'][$i] ) ) {
$text = $messages['text'][$i];
if ( ! empty( $text ) ) {
$text = wp_check_invalid_utf8( $text );
if ( ! empty( $text ) ) {
$text = sanitize_post_field( 'post_content', $text, 0, 'display' );
$text = stripslashes( $text );
}
} else {
$activ = null;
}
}
if ( ( ! is_null( $activ ) ) && ( ! empty( $activ ) ) && ( ! is_null( $prozent ) ) && ( ! is_null( $text ) ) ) {
if ( ! isset( $sorted[ $prozent ] ) ) {
$sorted[ $prozent ] = array(
'prozent' => $prozent,
'activ' => $activ,
'text' => $text,
);
}
}
}
}
if ( ! isset( $sorted[0] ) ) {
$sorted[0] = array(
'prozent' => 0,
'activ' => 1,
'text' => '',
);
}
$result = array();
if ( ! empty( $sorted ) ) {
ksort( $sorted );
foreach ( $sorted as $item ) {
$result['text'][] = $item['text'];
$result['prozent'][] = $item['prozent'];
$result['activ'][] = $item['activ'];
}
}
return $result;
} partials/attempt.php 0000666 00000007151 15214240763 0010566 0 ustar 00 post_title ) ? $quiz_attempt['post']->post_title : @$quiz_attempt['quiz_title'];
$quiz_link = ! empty( $quiz_attempt['post']->ID ) ? learndash_get_step_permalink( intval( $quiz_attempt['post']->ID ), $course_id ) : '#';
/**
* Only display the quiz if we've found a title
*
* @var [string] $quiz_title
*/
if ( ! empty( $quiz_title ) ) : ?>