UserModel, 'item_id' => int|string ]
*
* @throws Exception
*/
public function layout( array $data = [] ) {
try {
$userModel = $data['userModel'] ?? false;
if ( ! $userModel || ! $userModel->is_instructor() ) {
throw new Exception( __( 'You do not have permission to create or edit questions', 'learnpress' ) );
}
$item_id = $data['item_id'] ?? '';
if ( empty( $item_id ) ) {
throw new Exception( __( 'Invalid question ID', 'learnpress' ) );
}
/*if ( ! CourseBuilderAccessPolicy::can_access_tab_post( 'questions', $item_id ) ) {
throw new Exception( __( "Sorry, you don't have permission to access this content", 'learnpress' ) );
}*/
$is_create_new = $item_id === CourseBuilder::POST_NEW;
$questionModel = false;
if ( ! $is_create_new ) {
$questionModel = QuestionPostModel::find( (int) $item_id, true );
if ( ! $questionModel ) {
throw new Exception( __( 'Question not found', 'learnpress' ) );
}
$questionModel->check_capabilities_update_item_course();
if ( $questionModel->post_status === PostModel::STATUS_TRASH ) {
throw new Exception(
__(
'You cannot edit this item because it is in the Trash. Please restore it and try again.',
'learnpress'
)
);
}
} else {
$questionModelNew = new QuestionPostModel();
$questionModelNew->check_capabilities_create_item_course();
}
$data['questionModel'] = $questionModel;
$section = [
'wrap' => sprintf(
'
',
esc_attr( $item_id )
),
'header' => $this->html_header( $data ),
'tabs' => $this->html_tabs( $data ),
'wrap_end' => '
',
];
echo Template::combine_components( $section );
} catch ( Throwable $e ) {
Template::print_message( $e->getMessage(), 'error' );
}
}
public function html_header( array $data = [] ): string {
$userModel = $data['userModel'] ?? false;
if ( ! $userModel instanceof UserModel ) {
return '';
}
$questionModel = $data['questionModel'] ?? false;
$hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
$more_actions_icon = LP_WP_Filesystem::get_icon_svg( 'ico-cb-more.svg' );
$title = $questionModel ? $questionModel->get_the_title() : __( 'Add New Question', 'learnpress' );
$status = $questionModel ? $questionModel->post_status : '';
$status_label = 'future' === $status ? __( 'scheduled', 'learnpress' ) : $status;
$main_action_status = in_array( $status, [ 'publish', 'draft', 'pending', 'future', 'private' ], true ) ? $status : 'publish';
$wp_user = new WP_User( $userModel );
$hide_wp_edit_link = $hide_instructor_access_admin_screen && user_can( $wp_user, UserModel::ROLE_INSTRUCTOR );
$section = [
'header_wrap' => '',
];
return Template::combine_components( $section );
}
public function html_tabs( array $data = [] ): string {
$section_tab = [
'tabs_wrap' => '',
'tabs' => '',
'tabs_end' => '
',
];
$section_content = [
'wrap' => '',
'content' => '',
'wrap-end' => '
',
];
$tabs = apply_filters(
'learn-press/course-builder/questions/edit/tabs',
[
'overview' => [
'title' => esc_html__( 'Overview', 'learnpress' ),
'html' => $this->html_tab_overview( $data ),
],
'settings' => [
'title' => esc_html__( 'Settings', 'learnpress' ),
'html' => $this->html_tab_settings( $data ),
],
],
$data
);
$tab_sections = [];
foreach ( $tabs as $key => $tab ) {
$tab_sections[ $key ] = $tab['slug'] ?? $key;
}
$tab_active = (string) reset( $tab_sections );
if ( isset( $_GET['tab'] ) ) {
$requested_tab = sanitize_key( wp_unslash( $_GET['tab'] ) );
if ( in_array( $requested_tab, $tab_sections, true ) ) {
$tab_active = $requested_tab;
}
}
foreach ( $tabs as $key => $tab ) {
$tab_section = $tab_sections[ $key ];
$is_active = $tab_section === $tab_active;
$section_tab['tabs'] .= sprintf(
'%s',
$is_active ? 'is-active' : '',
esc_attr( $tab_section ),
esc_html( $tab['title'] ?? '' )
);
/**
* @uses html_tab_overview
* @uses html_tab_settings
*/
$section_content['content'] .= sprintf(
'%s
',
$is_active ? '' : 'lp-hidden',
esc_attr( $tab_section ),
$tab['html'] ?? ''
);
}
return Template::combine_components(
[
'tabs' => Template::combine_components( $section_tab ),
'contents' => Template::combine_components( $section_content ),
]
);
}
public function html_tab_overview( array $data = [] ): string {
wp_enqueue_script( 'lp-course-builder' );
$question_model = $data['questionModel'] ?? false;
$question_id = $data['item_id'] ?? ( $question_model ? $question_model->get_id() : CourseBuilder::POST_NEW );
if ( absint( $question_id ) && ! $question_model ) {
$question_model = QuestionPostModel::find( absint( $question_id ), true );
if ( empty( $question_model ) ) {
return '';
}
}
$html_assigned = $this->assigned_quiz( $question_model );
$html_edit_title = $this->edit_title( $question_model );
$html_permalink = $this->edit_permalink( $question_model );
$html_publish = $this->edit_publish( $question_model );
$html_edit_desc = $this->edit_desc( $question_model );
$section = [
'wrapper' => sprintf( '', $question_id ),
'content_wrapper' => '
',
'left_column' => '
',
'edit_title' => $html_edit_title,
'assigned_quiz' => $html_assigned,
'edit_permalink' => $html_permalink,
'edit_publish' => $html_publish,
'left_column_end' => '
',
'right_column' => '
',
'edit_desc' => $html_edit_desc,
'right_column_end' => '
',
'content_wrapper_end' => '
',
'wrapper_end' => '
',
];
return Template::combine_components( $section );
}
public function html_tab_settings( array $data = [] ): string {
wp_enqueue_style( 'lp-edit-question' );
$question_model = $data['questionModel'] ?? false;
$question_id = $data['item_id'] ?? ( $question_model ? $question_model->get_id() : CourseBuilder::POST_NEW );
if ( $question_id === CourseBuilder::POST_NEW || absint( $question_id ) <= 0 ) {
return sprintf( '%s', __( 'Please save Question before setting question', 'learnpress' ) );
}
if ( ! $question_model ) {
$question_model = QuestionPostModel::find( absint( $question_id ), true );
if ( empty( $question_model ) ) {
return '';
}
}
$settings = AdminEditQuestionTemplate::instance()->html_edit_question( $question_model );
$output = [
'wrapper' => sprintf( '', $question_id ),
'form_setting' => '',
'wrapper_end' => '
',
];
return Template::combine_components( $output );
}
/**
* Allow callback for AJAX.
* @use self::render_edit_course_curriculum
* @use self::render_html
*
* @param array $callbacks
*
* @return array
*/
public function allow_callback( array $callbacks ): array {
$callbacks[] = AdminEditCurriculumTemplate::class . ':render_edit_course_curriculum';
return $callbacks;
}
public function assigned_quiz( $question_model ) {
$assign_question = ! empty( $question_model ) ? $this->get_assigned_question( $question_model->get_id() ) : '';
$html_quizzes = '';
$assigned = sprintf( '%s', __( 'Not assigned yet', 'learnpress' ) );
if ( ! empty( $assign_question ) ) {
$quizzes = is_array( $assign_question ) && isset( $assign_question['id'] )
? array( $assign_question )
: $assign_question;
$quiz_htmls = array();
foreach ( $quizzes as $quiz ) {
$quiz_id = $quiz['id'] ?? 0;
$quiz_title = $quiz['title'] ?? '';
if ( $quiz_id && $quiz_title ) {
$quiz_link = BuilderQuizTemplate::instance()->get_link_edit( $quiz_id );
$quiz_htmls[] = sprintf(
'%s',
esc_url( $quiz_link ),
esc_html( $quiz_title )
);
}
}
if ( ! empty( $quiz_htmls ) ) {
$assigned = implode( ', ', $quiz_htmls );
}
}
$html_quizzes = sprintf(
'%s %s
',
__( 'Assigned', 'learnpress' ),
$assigned
);
return $html_quizzes;
}
public function edit_title( $question_model ) {
$title = ! empty( $question_model ) ? $question_model->get_the_title() : '';
$edit = [
'wrapper' => '',
'label' => sprintf( '', __( 'Title', 'learnpress' ) ),
'input' => sprintf( '', esc_attr( $title ) ),
'wrapper_end' => '
',
];
return Template::combine_components( $edit );
}
/**
* @param QuestionPostModel|false $question_model
* @return string
*/
public function edit_desc( $question_model ) {
$desc = ! empty( $question_model ) ? $question_model->post_content : '';
$editor_id = 'question_description_editor';
$editor_settings = array(
'textarea_name' => 'question_description',
'textarea_rows' => 10,
'teeny' => false,
'media_buttons' => true,
'tinymce' => array(
'content_style' => "body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; font-size: 14px; line-height: 1.6; color: #1e1e1e; }",
'toolbar1' => 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,spellchecker,wp_adv',
'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help',
),
'quicktags' => true,
);
$edit = [
'wrapper' => '',
'label' => sprintf( '', __( 'Description', 'learnpress' ) ),
'edit' => AdminTemplate::editor_tinymce(
$desc,
$editor_id,
$editor_settings
),
'wrapper_end' => '
',
];
return Template::combine_components( $edit );
}
public function edit_permalink( $question_model ): string {
$post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
if ( ! $post_id ) {
return Template::combine_components(
[
'wrapper' => '',
'label' => sprintf( '%s', __( 'Permalink', 'learnpress' ) ),
'content' => sprintf(
'%s',
__( 'Permalink will be available after saving.', 'learnpress' )
),
'wrapper_end' => '
',
]
);
}
$post = get_post( $post_id );
$post_name = $post ? $post->post_name : '';
$full_url = urldecode( (string) get_permalink( $post_id ) );
$display_data = $this->get_question_display_permalink_data( $post_id, (string) $post_name );
$display_url = (string) ( $display_data['url'] ?? '' );
$editor_slug = (string) ( $display_data['slug'] ?? '' );
if ( empty( $display_url ) ) {
$display_url = $full_url;
}
if ( empty( $full_url ) ) {
$full_url = $display_url;
}
if ( empty( $editor_slug ) ) {
$editor_slug = (string) $post_name;
}
if ( empty( $editor_slug ) && ! empty( $display_url ) ) {
$display_path = parse_url( $display_url, PHP_URL_PATH );
if ( is_string( $display_path ) && '' !== $display_path ) {
$editor_slug = basename( untrailingslashit( $display_path ) );
}
}
if ( empty( $full_url ) ) {
return Template::combine_components(
[
'wrapper' => '',
'label' => sprintf( '%s', __( 'Permalink', 'learnpress' ) ),
'content' => sprintf(
'%s',
__( 'Permalink is not available for this question.', 'learnpress' )
),
'wrapper_end' => '
',
]
);
}
$base_url = $display_url;
if (
! empty( $editor_slug ) &&
false === strpos( $display_url, '?p=' ) &&
false === strpos( $display_url, '&p=' ) &&
false === strpos( $display_url, '?lp_question=' ) &&
false === strpos( $display_url, '&lp_question=' )
) {
$base_url = trailingslashit( preg_replace( '/' . preg_quote( $editor_slug, '/' ) . '\/?$/', '', $display_url ) );
}
$state_a = sprintf(
'%s
',
__( 'Permalink', 'learnpress' ),
esc_url( $full_url ),
esc_html( $display_url ),
__( 'Edit', 'learnpress' )
);
$state_b = sprintf(
'',
esc_html( $base_url ),
esc_attr( $editor_slug ),
esc_attr__( 'your-slug', 'learnpress' ),
__( 'OK', 'learnpress' ),
__( 'Cancel', 'learnpress' )
);
$hidden_base = sprintf(
'',
esc_attr( $base_url )
);
$view = [
'wrapper' => '',
'state_a' => $state_a,
'state_b' => $state_b,
'hidden_base' => $hidden_base,
'wrapper_end' => '
',
];
return Template::combine_components( $view );
}
/**
* Get permalink display URL in publish-style format for editing slug.
*
* @param int $post_id
* @param string $post_name
*
* @return array
*/
private function get_question_display_permalink_data( int $post_id, string $post_name = '' ): array {
$display_url = urldecode( (string) get_permalink( $post_id ) );
$sample_slug = $post_name;
if ( ! function_exists( 'get_sample_permalink' ) ) {
require_once ABSPATH . 'wp-admin/includes/post.php';
}
if ( function_exists( 'get_sample_permalink' ) ) {
$sample_permalink = get_sample_permalink( $post_id );
if ( is_array( $sample_permalink ) && ! empty( $sample_permalink[0] ) ) {
$sample_slug = ! empty( $sample_permalink[1] ) ? (string) $sample_permalink[1] : $sample_slug;
$display_url = str_replace(
[ '%postname%', '%pagename%' ],
$sample_slug,
(string) $sample_permalink[0]
);
}
}
return [
'url' => urldecode( $display_url ),
'slug' => urldecode( (string) $sample_slug ),
];
}
public function edit_publish( $question_model ): string {
$post_id = ! empty( $question_model ) ? absint( $question_model->get_id() ) : 0;
$post = $post_id ? get_post( $post_id ) : null;
$current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : 'draft';
$status_value = 'draft' === $current_status ? 'draft' : 'publish';
$status_options_html = sprintf(
'',
selected( $status_value, 'publish', false ),
esc_html__( 'Published', 'learnpress' ),
selected( $status_value, 'draft', false ),
esc_html__( 'Draft', 'learnpress' )
);
$publish = [
'wrapper' => '',
'title' => sprintf( '
%s
', esc_html__( 'Publish', 'learnpress' ) ),
'status_row' => sprintf(
'
',
esc_html__( 'Status', 'learnpress' ),
$status_options_html
),
'wrapper_end' => '
',
];
return Template::combine_components( $publish );
}
public function get_assigned_question( $id ) {
$curd = new LP_Question_CURD();
$quiz = $curd->get_quiz( $id );
if ( $quiz ) {
return array(
'id' => $quiz->ID,
'title' => $quiz->post_title ?? '',
);
}
return false;
}
}