LearnPress – WordPress LMS Plugin - Version 3.0.2

Version Description

~ Fixed PHP non-numeric cast type ~ Improved admin ajax for course/quiz/question editor ~ Fixed error when extending method from parent ~ Fixed invalid course progress label ~ Fixed invalid filter to course passing grade ~ Fixed empty course item class for other post types

Download this release

Release Info

Developer tunnhn
Plugin Icon 128x128 LearnPress – WordPress LMS Plugin
Version 3.0.2
Comparing to
See all releases

Code changes from version 3.0.1 to 3.0.2

assets/js/admin/course-editor.js CHANGED
@@ -593,7 +593,7 @@ var LP_Choose_Items_Modal_Store = (function (exports, Vue, helpers, data) {
593
autoDraft: function (state) {
594
return state.auto_draft;
595
},
596
- disable_curriculum: function(state){
597
return state.disable_curriculum;
598
},
599
status: function (state) {
@@ -656,7 +656,7 @@ var LP_Choose_Items_Modal_Store = (function (exports, Vue, helpers, data) {
656
Vue.http.LPRequest({
657
type: 'draft-course',
658
course: JSON.stringify(payload)
659
- }).then(function(response) {
660
var result = response.body;
661
662
if (!result.success) {
@@ -732,6 +732,11 @@ var LP_Choose_Items_Modal_Store = (function (exports, Vue, helpers, data) {
732
$store.dispatch('newRequest');
733
734
next(function (response) {
735
var body = response.body;
736
var result = body.success || false;
737
593
autoDraft: function (state) {
594
return state.auto_draft;
595
},
596
+ disable_curriculum: function (state) {
597
return state.disable_curriculum;
598
},
599
status: function (state) {
656
Vue.http.LPRequest({
657
type: 'draft-course',
658
course: JSON.stringify(payload)
659
+ }).then(function (response) {
660
var result = response.body;
661
662
if (!result.success) {
732
$store.dispatch('newRequest');
733
734
next(function (response) {
735
+
736
+ if (!jQuery.isPlainObject(response.body)) {
737
+ response.body = LP.parseJSON(response.body);
738
+ }
739
+
740
var body = response.body;
741
var result = body.success || false;
742
assets/js/admin/question-editor.js CHANGED
@@ -251,6 +251,11 @@
251
$store.dispatch('newRequest');
252
253
next(function (response) {
254
var body = response.body;
255
var result = body.success || false;
256
251
$store.dispatch('newRequest');
252
253
next(function (response) {
254
+
255
+ if (!jQuery.isPlainObject(response.body)) {
256
+ response.body = LP.parseJSON(response.body);
257
+ }
258
+
259
var body = response.body;
260
var result = body.success || false;
261
assets/js/admin/quiz-editor.js CHANGED
@@ -875,6 +875,11 @@ var LP_List_Quiz_Questions_Store = (function (Vue, helpers, data, $) {
875
$store.dispatch('newRequest');
876
877
next(function (response) {
878
var body = response.body,
879
result = body.success || false;
880
875
$store.dispatch('newRequest');
876
877
next(function (response) {
878
+
879
+ if (!jQuery.isPlainObject(response.body)) {
880
+ response.body = LP.parseJSON(response.body);
881
+ }
882
+
883
var body = response.body,
884
result = body.success || false;
885
inc/admin/class-lp-admin-ajax.php CHANGED
@@ -111,297 +111,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
111
* @since 3.0.0
112
*/
113
public static function admin_course_editor() {
114
-
115
- check_ajax_referer( 'learnpress_update_curriculum', 'nonce' );
116
-
117
- $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
118
-
119
- $course_id = $args['id'];
120
- $course = learn_press_get_course( $course_id );
121
-
122
- if ( ! $course ) {
123
- wp_send_json_error();
124
- }
125
-
126
- // course curd
127
- $course_curd = new LP_Course_CURD();
128
- // section curd
129
- $section_curd = new LP_Section_CURD( $course_id );
130
-
131
- $result = $args['type'];
132
-
133
- switch ( $args['type'] ) {
134
-
135
- case 'heartbeat':
136
- $result = true;
137
- break;
138
-
139
- case 'draft-course':
140
- $new_course = ! empty( $args['course'] ) ? $args['course'] : false;
141
- $new_course = json_decode( wp_unslash( $new_course ), true );
142
-
143
- if ( ! $new_course ) {
144
- break;
145
- }
146
-
147
- $title = $new_course['title'] ? $new_course['title'] : __( 'New Course', 'learnpress' );
148
- $content = $new_course['content'] ? $new_course['content'] : '';
149
-
150
- $args = array(
151
- 'id' => $course_id,
152
- 'status' => 'draft',
153
- 'title' => $title,
154
- 'content' => $content
155
- );
156
-
157
- $course_curd->create( $args );
158
- break;
159
-
160
- case 'hidden-sections':
161
- // get hidden sections id
162
- $hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
163
- // update course post meta
164
- update_post_meta( $course_id, '_admin_hidden_sections', $hidden );
165
- break;
166
-
167
- case 'sort-sections':
168
- $order = ! empty( $args['order'] ) ? $args['order'] : false;
169
- $order = json_decode( wp_unslash( $order ), true );
170
-
171
- if ( ! $order ) {
172
- break;
173
- }
174
-
175
- $result = $section_curd->sort_sections( $order );
176
-
177
- // last section
178
- $last_section_id = end( $order );
179
- // update final quiz
180
- $section_curd->update_final_quiz( $last_section_id );
181
- break;
182
-
183
- case 'update-section':
184
- $section = ! empty( $args['section'] ) ? $args['section'] : false;
185
- $section = json_decode( wp_unslash( $section ), true );
186
-
187
- if ( ! $section ) {
188
- break;
189
- }
190
-
191
- $update = array(
192
- 'section_id' => $section['id'],
193
- 'section_name' => $section['title'],
194
- 'section_description' => $section['description'],
195
- 'section_order' => $section['order'],
196
- 'section_course_id' => $section['course_id'],
197
- );
198
-
199
- $result = $section_curd->update( $update );
200
- break;
201
-
202
- case 'remove-section':
203
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
204
-
205
- if ( ! $section_id ) {
206
- break;
207
- }
208
-
209
- $section_curd->delete( $section_id );
210
- break;
211
-
212
- case 'new-section':
213
- $section_name = ! empty( $args['section_name'] ) ? $args['section_name'] : false;
214
-
215
- $args = array(
216
- 'section_course_id' => $course_id,
217
- 'section_description' => '',
218
- 'section_name' => $section_name,
219
- 'items' => array(),
220
- );
221
-
222
- // create section
223
- $section = $section_curd->create( $args );
224
-
225
- $result = array(
226
- 'id' => $section['section_id'],
227
- 'items' => $section['items'],
228
- 'title' => $section['section_name'],
229
- 'description' => $section['section_description'],
230
- 'course_id' => $section['section_course_id'],
231
- 'order' => $section['section_order'],
232
- );
233
- break;
234
-
235
- case 'update-section-item':
236
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
237
- $item = ! empty( $args['item'] ) ? $args['item'] : false;
238
- $item = json_decode( wp_unslash( $item ), true );
239
-
240
- if ( ! ( $section_id && $item ) ) {
241
- break;
242
- }
243
-
244
- // update lesson, quiz title
245
- $result = $section_curd->update_item( $item );
246
- break;
247
-
248
- case 'remove-section-item':
249
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
250
- $item_id = ! empty( $args['item_id'] ) ? $args['item_id'] : false;
251
-
252
- if ( ! ( $section_id && $item_id ) ) {
253
- break;
254
- }
255
-
256
- // remove item from course
257
- $course_curd->remove_item( $item_id );
258
- break;
259
-
260
- case 'delete-section-item':
261
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
262
- $item_id = ! empty( $args['item_id'] ) ? $args['item_id'] : false;
263
-
264
- if ( ! ( $section_id && $item_id ) ) {
265
- break;
266
- }
267
-
268
- $result = wp_delete_post( $item_id );
269
- break;
270
-
271
- case 'new-section-item':
272
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
273
- $item = ! empty( $args['item'] ) ? $args['item'] : false;
274
- $item = json_decode( wp_unslash( $item ), true );
275
-
276
- if ( ! ( $section_id && $item ) ) {
277
- break;
278
- }
279
-
280
- // create new lesson, quiz and add to course
281
- $result = $section_curd->new_item( $section_id, $item );
282
- break;
283
-
284
- case 'update-section-items':
285
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
286
- $last_section = ! empty( $args['last_section'] ) ? $args['last_section'] : false;
287
- $items = ! empty( $args['items'] ) ? $args['items'] : false;
288
- $items = json_decode( wp_unslash( $items ), true );
289
-
290
- if ( ! ( $section_id && $items ) ) {
291
- break;
292
- }
293
-
294
- $result = $section_curd->update_section_items( $section_id, $items );
295
-
296
- if ( $last_section ) {
297
- $section_curd->update_final_quiz( $section_id );
298
- }
299
- break;
300
-
301
- case 'search-items':
302
- $query = isset( $args['query'] ) ? $args['query'] : '';
303
- $type = isset( $args['item_type'] ) ? $args['item_type'] : '';
304
- $page = ! empty( $args['page'] ) ? $args['page'] : 1;
305
- $exclude = ! empty( $args['exclude'] ) ? $args['exclude'] : '';
306
-
307
- if ( $exclude ) {
308
- $exclude = json_decode( $exclude, true );
309
- }
310
-
311
- $ids_exclude = array();
312
-
313
- if ( is_array( $exclude ) ) {
314
- foreach ( $exclude as $item ) {
315
- $ids_exclude[] = $item['id'];
316
- }
317
- }
318
-
319
- $search = new LP_Modal_Search_Items( array(
320
- 'type' => $type,
321
- 'context' => 'course',
322
- 'context_id' => $course_id,
323
- 'term' => $query,
324
- 'limit' => apply_filters( 'learn-press/course-editor/choose-items-limit', 10 ),
325
- 'paged' => $page,
326
- 'exclude' => $ids_exclude,
327
- ) );
328
-
329
- $id_items = $search->get_items();
330
-
331
- $items = array();
332
- foreach ( $id_items as $id ) {
333
- $post = get_post( $id );
334
-
335
- $items[] = array(
336
- 'id' => $post->ID,
337
- 'title' => $post->post_title,
338
- 'type' => $post->post_type,
339
- );
340
- }
341
-
342
- $result = array(
343
- 'items' => $items,
344
- 'pagination' => $search->get_pagination( false )
345
- );
346
- break;
347
-
348
- case 'add-items-to-section':
349
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
350
- $items = ! empty( $args['items'] ) ? $args['items'] : false;
351
- $items = json_decode( wp_unslash( $items ), true );
352
-
353
- if ( ! $items || ! $section_id ) {
354
- break;
355
- }
356
-
357
- $result = $section_curd->add_items_section( $section_id, $items );
358
- break;
359
-
360
- default:
361
- break;
362
-
363
- }
364
-
365
- if ( is_wp_error( $result ) ) {
366
- wp_send_json_error( $result->get_error_message() );
367
- }
368
-
369
- wp_send_json_success( $result );
370
- }
371
-
372
- /**
373
- * Draft question.
374
- *
375
- * @since 3.0.0
376
- *
377
- * @param $question_id
378
- * @param array $args
379
- *
380
- * @return bool|int|LP_Question
381
- */
382
- private static function draft_question( $question_id, $args = array() ) {
383
-
384
- if ( get_post_status( $question_id ) != 'auto-draft' ) {
385
- return false;
386
- }
387
-
388
- $curd = new LP_Question_CURD();
389
-
390
- $args = wp_parse_args( $args, array(
391
- 'id' => $question_id,
392
- 'title' => __( 'New Question', 'learnpress' ),
393
- 'content' => '',
394
- 'status' => 'draft',
395
- 'create_answers' => false
396
- ) );
397
-
398
- $question = $curd->create( $args );
399
-
400
- if ( ! $question ) {
401
- return false;
402
- }
403
-
404
- return $question;
405
}
406
407
/**
@@ -410,127 +121,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
410
* @since 3.0.0
411
*/
412
public static function admin_question_editor() {
413
-
414
- check_ajax_referer( 'learnpress_admin_question_editor', 'nonce' );
415
-
416
- $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
417
-
418
- // question id
419
- $question_id = $args['id'];
420
- $question = LP_Question::get_question( $question_id );
421
-
422
- if ( ! $question ) {
423
- wp_send_json_error();
424
- }
425
-
426
- $curd = new LP_Question_CURD();
427
- $result = array();
428
- $result['status'] = false;
429
-
430
- switch ( $args['type'] ) {
431
-
432
- case 'change-question-type':
433
- $type = ! empty( $args['question_type'] ) ? $args['question_type'] : false;
434
-
435
- if ( ! $type ) {
436
- break;
437
- }
438
-
439
- // draft question args
440
- $args = $args['draft_question'] ? $args['draft_question'] : '';
441
-
442
- if ( $args ) {
443
- $args = (array) ( json_decode( wp_unslash( $args ), '' ) );
444
- $draft = self::draft_question( $question_id, $args );
445
-
446
- // check if draft question false or question exist
447
- if ( $draft ) {
448
- $question = $draft;
449
- }
450
- }
451
-
452
- // change question type
453
- $question = $curd->change_question_type( $question, $type );
454
-
455
- if ( $question ) {
456
- $result = LP_Admin_Ajax::get_question_data_to_question_editor( $question, true );
457
- }
458
- break;
459
-
460
- case 'sort-answer' :
461
- // answers order
462
- $order = ! empty( $args['order'] ) ? $args['order'] : false;
463
-
464
- if ( ! $order ) {
465
- break;
466
- }
467
-
468
- // sort answers
469
- $question = $curd->sort_answers( $question_id, $order );
470
-
471
- $result = array_values( $question->get_data( 'answer_options' ) );
472
- break;
473
-
474
- case 'update-answer-title':
475
- // answers
476
- $answer = ! empty( $args['answer'] ) ? $args['answer'] : false;
477
- $answer = json_decode( wp_unslash( $answer ), true );
478
-
479
- if ( ! $answer ) {
480
- break;
481
- }
482
-
483
- // update answer title
484
- $result = $curd->update_answer_title( $question_id, $answer );
485
- break;
486
-
487
- case 'change-correct':
488
- // correct answer
489
- $correct = ! empty( $args['correct'] ) ? $args['correct'] : false;
490
- $correct = json_decode( wp_unslash( $correct ), true );
491
-
492
- if ( ! $correct ) {
493
- break;
494
- }
495
-
496
- // update correct answer
497
- $question = $curd->change_correct_answer( $question, $correct );
498
-
499
- $result = $question->get_data( 'answer_options' );
500
- break;
501
-
502
- case 'delete-answer' :
503
- // answer id
504
- $answer_id = ! empty( $args['answer_id'] ) ? $args['answer_id'] : false;
505
-
506
- if ( ! $answer_id ) {
507
- break;
508
- }
509
-
510
- // delete answer
511
- $curd->delete_answer( $question_id, $answer_id );
512
-
513
- $result = $question->get_data( 'answer_options' );
514
- break;
515
-
516
- case 'new-answer' :
517
- // new answer
518
- $answer = LP_Question::get_default_answer();
519
- // add new
520
- $curd->new_answer( $question_id, $answer );
521
-
522
- $result = $question->get_data( 'answer_options' );
523
- break;
524
-
525
- default:
526
- break;
527
- }
528
-
529
- if ( is_wp_error( $result ) ) {
530
- wp_send_json_error( $result->get_error_message() );
531
- }
532
-
533
- wp_send_json_success( $result );
534
}
535
536
/**
@@ -539,393 +131,25 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
539
* @since 3.0.0
540
*/
541
public static function admin_quiz_editor() {
542
543
- check_ajax_referer( 'learnpress_admin_quiz_editor', 'nonce' );
544
-
545
- $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
546
-
547
- // get quiz
548
- $quiz_id = $args['id'];
549
- $quiz = learn_press_get_quiz( $quiz_id );
550
-
551
- if ( ! $quiz ) {
552
- wp_send_json_error();
553
- }
554
-
555
- $quiz_curd = new LP_Quiz_CURD();
556
- $question_curd = new LP_Question_CURD();
557
-
558
- $result = array();
559
- $result['status'] = false;
560
-
561
- switch ( $args['type'] ) {
562
- case 'heartbeat' :
563
- $result = true;
564
- break;
565
-
566
- case 'hidden-questions':
567
- $hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
568
- update_post_meta( $quiz_id, '_lp_hidden_questions', $hidden );
569
- break;
570
-
571
- case 'new-question':
572
- // new question
573
- $question = ! empty( $args['question'] ) ? $args['question'] : false;
574
- $question = json_decode( wp_unslash( $question ), true );
575
-
576
- if ( ! $question ) {
577
- break;
578
- }
579
-
580
- // draft quiz
581
- if ( get_post_status( $quiz_id ) == 'auto-draft' ) {
582
-
583
- $draft_quiz = ! empty( $args['draft_quiz'] ) ? $args['draft_quiz'] : '';
584
- $draft_quiz = (array) ( json_decode( wp_unslash( $draft_quiz ), '' ) );
585
-
586
- $quiz_args = array(
587
- 'id' => $quiz_id,
588
- 'title' => $draft_quiz['title'] ? $draft_quiz['title'] : __( 'New Quiz', 'learnpress' ),
589
- 'content' => $draft_quiz['content'],
590
- 'status' => 'draft'
591
- );
592
-
593
- $quiz_id = $quiz_curd->create( $quiz_args );
594
- }
595
-
596
- if ( ! $quiz_id ) {
597
- $result = new WP_Error( __( 'Quiz creation failed.', 'learnpress' ) );
598
- break;
599
- }
600
-
601
- $args = array(
602
- 'quiz_id' => $quiz_id,
603
- 'title' => $question['title'],
604
- 'type' => $question['type'],
605
- );
606
-
607
- $new_question = $question_curd->create( $args );
608
-
609
- if ( ! is_wp_error( $new_question ) ) {
610
-
611
- // update hidden questions in quiz meta
612
- $quiz = LP_Quiz::get_quiz( $quiz_id );
613
- $hidden_questions = $quiz->get_questions();
614
- if ( $hidden_questions ) {
615
- unset( $hidden_questions[ $new_question->get_id() ] );
616
- $hidden_questions = array_keys( $hidden_questions );
617
- }
618
- update_post_meta( $quiz_id, '_lp_hidden_questions', $hidden_questions );
619
-
620
- // get new question data
621
- $result = LP_Admin_Ajax::get_question_data_to_quiz_editor( $new_question, true, array( 'open' => true ) );
622
- }
623
- break;
624
-
625
- case 'sort-questions':
626
- $order = ! empty( $args['order'] ) ? $args['order'] : false;
627
- $order = json_decode( wp_unslash( $order ), true );
628
-
629
- if ( ! $order ) {
630
- break;
631
- }
632
-
633
- $result = $quiz_curd->sort_questions( $order );
634
- break;
635
-
636
- case 'update-question-title':
637
- $question = ! empty( $args['question'] ) ? $args['question'] : false;
638
- $question = json_decode( wp_unslash( $question ), true );
639
-
640
- if ( ! $question ) {
641
- break;
642
- }
643
-
644
- wp_update_post( array( 'ID' => $question['id'], 'post_title' => $question['title'] ) );
645
-
646
- $result['status'] = true;
647
- break;
648
-
649
- case 'change-question-type':
650
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
651
- $type = ! empty( $args['question_type'] ) ? $args['question_type'] : false;
652
-
653
- if ( ! ( $question_id || $type ) ) {
654
- break;
655
- }
656
-
657
- $question = LP_Question::get_question( $question_id );
658
-
659
- // change question type
660
- $question = $question_curd->change_question_type( $question, $type );
661
-
662
- $result = LP_Admin_Ajax::get_question_data_to_quiz_editor( $question, true );
663
- break;
664
-
665
- case 'clone-question':
666
- $question = ! empty( $args['question'] ) ? $args['question'] : false;
667
- $question = json_decode( wp_unslash( $question ), true );
668
-
669
- if ( ! $question ) {
670
- break;
671
- }
672
-
673
- // duplicate question
674
- $new_question_id = $question_curd->duplicate( $question['id'], array( 'post_status' => 'publish' ) );
675
-
676
- if ( ! is_wp_error( $new_question_id ) ) {
677
-
678
- // add question to hidden questions in quiz meta
679
- $hidden_questions = get_post_meta( $quiz_id, '_lp_hidden_questions', true );
680
- if ( ! $hidden_questions ) {
681
- $hidden_questions = array();
682
- }
683
- $hidden_questions[] = $new_question_id;// add question to hidden questions in quiz meta
684
- update_post_meta( $quiz_id, '_lp_hidden_questions', $hidden_questions );
685
-
686
- // add question to quiz
687
- $quiz_curd->add_question( $quiz_id, $new_question_id );
688
-
689
- $result = LP_Admin_Ajax::get_question_data_to_quiz_editor( $new_question_id );
690
- }
691
- break;
692
-
693
- case 'remove-question':
694
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
695
-
696
- if ( ! $question_id ) {
697
- break;
698
- }
699
-
700
- $result = $quiz_curd->remove_questions( $quiz_id, $question_id );
701
- break;
702
-
703
- case 'delete-question':
704
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
705
-
706
- if ( ! $question_id ) {
707
- break;
708
- }
709
-
710
- $result = wp_delete_post( $question_id );
711
- break;
712
-
713
- case 'sort-question-answers':
714
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
715
-
716
- $order = ! empty( $args['order'] ) ? $args['order'] : false;
717
- $order = json_decode( wp_unslash( $order ), true );
718
-
719
-
720
- if ( ! ( $question_id && $order ) ) {
721
- break;
722
- }
723
-
724
- // sort answer
725
- $result = $question_curd->sort_answers( $question_id, $order );
726
- break;
727
-
728
- case 'update-question-answer-title':
729
- // question id
730
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
731
-
732
- // answers
733
- $answer = ! empty( $args['answer'] ) ? $args['answer'] : false;
734
- $answer = json_decode( wp_unslash( $answer ), true );
735
-
736
- if ( ! ( $question_id && $answer ) ) {
737
- break;
738
- }
739
-
740
- // update answer title
741
- $result = $question_curd->update_answer_title( $question_id, $answer );
742
- break;
743
-
744
- case 'change-question-correct-answer':
745
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
746
-
747
- // correct answer
748
- $correct = ! empty( $args['correct'] ) ? $args['correct'] : false;
749
- $correct = json_decode( wp_unslash( $correct ), true );
750
-
751
- if ( ! ( $question_id && $correct ) ) {
752
- break;
753
- }
754
-
755
- $question = LP_Question::get_question( $question_id );
756
- // update correct answer, get new question
757
- $question = $question_curd->change_correct_answer( $question, $correct );
758
-
759
- $result = LP_Admin_Ajax::get_question_data_to_quiz_editor( $question, true );
760
- break;
761
-
762
- case 'delete-question-answer':
763
- $question_id = isset( $_POST['question_id'] ) ? $_POST['question_id'] : false;
764
- $answer_id = isset( $_POST['answer_id'] ) ? intval( $_POST['answer_id'] ) : false;
765
-
766
- if ( ! ( $question_id && $answer_id ) ) {
767
- break;
768
- }
769
-
770
- $result = $question_curd->delete_answer( $question_id, $answer_id );
771
- break;
772
-
773
- case 'new-question-answer':
774
- $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
775
-
776
- if ( ! $question_id ) {
777
- break;
778
- }
779
-
780
- // new answer
781
- $answer = LP_Question::get_default_answer();
782
- // add new
783
- $new_answer_id = $question_curd->new_answer( $question_id, $answer );
784
-
785
- $question = LP_Question::get_question( $question_id );
786
-
787
- if ( $new_answer_id ) {
788
- $result = array_merge( $answer, array(
789
- 'question_answer_id' => $new_answer_id,
790
- 'question_id' => $question_id,
791
- 'answer_order' => count( $question->get_data( 'answer_options' ) )
792
- ) );
793
- }
794
- break;
795
-
796
- case 'update-question-content':
797
- $question = ! empty( $args['question'] ) ? $args['question'] : false;
798
- $question = json_decode( wp_unslash( $question ), true );
799
-
800
- if ( ! $question ) {
801
- break;
802
- }
803
-
804
- wp_update_post( array(
805
- 'ID' => $question['id'],
806
- 'post_content' => $question['settings']['content']
807
- ) );
808
-
809
- $result['status'] = true;
810
- break;
811
-
812
- case 'update-question-meta':
813
- $question = ! empty( $args['question'] ) ? $args['question'] : false;
814
- $question = json_decode( wp_unslash( $question ), true );
815
-
816
- $meta_key = ! empty( $args['meta_key'] ) ? $args['meta_key'] : false;
817
-
818
- if ( ! ( $question && $meta_key ) ) {
819
- break;
820
- }
821
-
822
- update_post_meta( $question['id'], '_lp_' . $meta_key, $question['settings'][ $meta_key ] );
823
-
824
- $result['status'] = true;
825
- break;
826
-
827
- case 'search-items':
828
- $query = ! empty( $args['query'] ) ? $args['query'] : '';
829
- $page = ! empty( $args['page'] ) ? intval( $args['page'] ) : 1;
830
- $exclude = ! empty( $args['exclude'] ) ? intval( $args['exclude'] ) : '';
831
-
832
- if ( $exclude ) {
833
- $exclude = json_decode( $exclude, true );
834
- }
835
-
836
- $ids_exclude = array();
837
- if ( is_array( $exclude ) ) {
838
- foreach ( $exclude as $item ) {
839
- $ids_exclude[] = $item['id'];
840
- }
841
- }
842
-
843
- $search = new LP_Modal_Search_Items( array(
844
- 'type' => 'lp_question',
845
- 'context' => 'quiz',
846
- 'context_id' => $quiz_id,
847
- 'term' => $query,
848
- 'limit' => apply_filters( 'learn-press/quiz-editor/choose-items-limit', 10 ),
849
- 'paged' => $page,
850
- 'exclude' => $ids_exclude
851
- ) );
852
-
853
- $ids_item = $search->get_items();
854
-
855
- $items = array();
856
- foreach ( $ids_item as $id ) {
857
- $post = get_post( $id );
858
-
859
- $items[] = array(
860
- 'id' => $post->ID,
861
- 'title' => $post->post_title,
862
- 'type' => $post->post_type
863
- );
864
- }
865
-
866
- $result = array(
867
- 'items' => $items,
868
- 'pagination' => $search->get_pagination( false )
869
- );
870
- break;
871
-
872
- case 'add-questions-to-quiz':
873
- // added questions
874
- $questions = isset( $_POST['items'] ) ? $_POST['items'] : false;
875
- $questions = json_decode( wp_unslash( $questions ), true );
876
-
877
- if ( ! $questions ) {
878
- break;
879
- }
880
-
881
- // draft quiz
882
- if ( get_post_status( $quiz_id ) == 'auto-draft' ) {
883
-
884
- $draft_quiz = ! empty( $args['draft_quiz'] ) ? $args['draft_quiz'] : '';
885
- $draft_quiz = (array) ( json_decode( wp_unslash( $draft_quiz ), '' ) );
886
-
887
- $quiz_args = array(
888
- 'id' => $quiz_id,
889
- 'title' => $draft_quiz['title'],
890
- 'content' => $draft_quiz['content'],
891
- 'status' => 'draft'
892
- );
893
-
894
- $quiz_id = $quiz_curd->create( $quiz_args );
895
- }
896
-
897
- if ( ! $quiz_id ) {
898
- $result = new WP_Error( __( 'Quiz creation failed.', 'learnpress' ) );
899
- break;
900
- }
901
-
902
- if ( $questions ) {
903
- // add question to hidden questions in quiz meta
904
- $hidden_questions = get_post_meta( $quiz_id, '_lp_hidden_questions', true );
905
- if ( ! $hidden_questions ) {
906
- $hidden_questions = array();
907
- }
908
-
909
- foreach ( $questions as $key => $question ) {
910
- // add question to hidden questions in quiz meta
911
- $hidden_questions[] = $question['id'];
912
- update_post_meta( $quiz_id, '_lp_hidden_questions', $hidden_questions );
913
- // add question to quiz
914
- $quiz_curd->add_question( $quiz_id, $question['id'] );
915
- }
916
- $result = $quiz->quiz_editor_get_questions();
917
- }
918
- break;
919
-
920
- default:
921
- break;
922
- }
923
924
if ( is_wp_error( $result ) ) {
925
- wp_send_json_error( $result->get_error_message() );
926
}
927
928
- wp_send_json_success( $result );
929
}
930
931
/**
@@ -977,91 +201,6 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
977
}
978
}
979
980
- /**
981
- * Get question data in admin question editor.
982
- *
983
- * @since 3.0.0
984
- *
985
- * @param $question
986
- * @param $object | if true, input in question object, do not need init LP_Question::get_question()
987
- *
988
- * @return array
989
- */
990
- public static function get_question_data_to_question_editor( $question, $object = false ) {
991
-
992
- if ( ! $object ) {
993
- if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
994
- return array();
995
- }
996
-
997
- // get question
998
- $question = LP_Question::get_question( $question );
999
- }
1000
-
1001
- // question id
1002
- $question_id = $question->get_id();
1003
-
1004
- $data = array(
1005
- 'id' => $question_id,
1006
- 'open' => false,
1007
- 'title' => get_the_title( $question_id ),
1008
- 'type' => array(
1009
- 'key' => $question->get_type(),
1010
- 'label' => $question->get_type_label()
1011
- ),
1012
- 'answers' => is_array( $question->get_data( 'answer_options' ) ) ? array_values( $question->get_data( 'answer_options' ) ) : array()
1013
- );
1014
-
1015
- return $data;
1016
- }
1017
-
1018
- /**
1019
- * Get question data in admin quiz editor.
1020
- *
1021
- * @since 3.0.0
1022
- *
1023
- * @param $question
1024
- * @param $object | if true, input in question object, do not need init LP_Question::get_question()
1025
- * @param array $args
1026
- *
1027
- * @return array
1028
- */
1029
- public static function get_question_data_to_quiz_editor( $question, $object = false, $args = array() ) {
1030
-
1031
- if ( ! $object ) {
1032
- if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
1033
- return array();
1034
- }
1035
-
1036
- // get question
1037
- $question = LP_Question::get_question( $question );
1038
- }
1039
-
1040
- // question id
1041
- $question_id = $question->get_id();
1042
- // question answer
1043
- $answers = array_values( $question->get_data( 'answer_options' ) );
1044
-
1045
- $data = wp_parse_args( $args, array(
1046
- 'id' => $question_id,
1047
- 'open' => false,
1048
- 'title' => get_the_title( $question_id ),
1049
- 'type' => array(
1050
- 'key' => $question->get_type(),
1051
- 'label' => $question->get_type_label()
1052
- ),
1053
- 'answers' => $answers,
1054
- 'settings' => array(
1055
- 'mark' => get_post_meta( $question_id, '_lp_mark', true ),
1056
- 'explanation' => get_post_meta( $question_id, '_lp_explanation', true ),
1057
- 'hint' => get_post_meta( $question_id, '_lp_hint', true )
1058
- ),
1059
- 'order' => count( $answers )
1060
- ) );
1061
-
1062
- return $data;
1063
- }
1064
-
1065
/**
1066
* Update ordering of payments when user changing.
1067
*
111
* @since 3.0.0
112
*/
113
public static function admin_course_editor() {
114
+ $editor = LP_Admin_Editor::get_editor_course();
115
+ self::admin_editor( $editor );
116
}
117
118
/**
121
* @since 3.0.0
122
*/
123
public static function admin_question_editor() {
124
+ $editor = LP_Admin_Editor::get_editor_question();
125
+ self::admin_editor( $editor );
126
}
127
128
/**
131
* @since 3.0.0
132
*/
133
public static function admin_quiz_editor() {
134
+ $editor = LP_Admin_Editor::get_editor_quiz();
135
+ self::admin_editor( $editor );
136
+ }
137
138
+ /**
139
+ * @since 3.0.2
140
+ *
141
+ * @param LP_Admin_Editor $editor
142
+ */
143
+ public static function admin_editor( &$editor ) {
144
+ $result = $editor->dispatch();
145
146
if ( is_wp_error( $result ) ) {
147
+ learn_press_send_json_error( $result->get_error_message() );
148
+ } elseif ( ! $result ) {
149
+ learn_press_send_json_error();
150
}
151
152
+ learn_press_send_json_success( $result );
153
}
154
155
/**
201
}
202
}
203
204
/**
205
* Update ordering of payments when user changing.
206
*
inc/admin/class-lp-admin.php CHANGED
@@ -706,6 +706,7 @@ if ( ! class_exists( 'LP_Admin' ) ) {
706
include_once 'class-lp-admin-dashboard.php';
707
include_once 'class-lp-admin-tools.php';
708
include_once 'class-lp-admin-ajax.php';
709
include_once 'class-lp-admin-menu.php';
710
include_once 'class-lp-meta-box-tabs.php';
711
include_once 'helpers/class-lp-outdated-template-helper.php';
706
include_once 'class-lp-admin-dashboard.php';
707
include_once 'class-lp-admin-tools.php';
708
include_once 'class-lp-admin-ajax.php';
709
+ include_once 'editor/class-lp-admin-editor.php';
710
include_once 'class-lp-admin-menu.php';
711
include_once 'class-lp-meta-box-tabs.php';
712
include_once 'helpers/class-lp-outdated-template-helper.php';
inc/admin/editor/class-lp-admin-editor-course.php ADDED
@@ -0,0 +1,363 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Admin_Editor_Course
5
+ *
6
+ * @since 3.0.2
7
+ */
8
+ class LP_Admin_Editor_Course extends LP_Admin_Editor {
9
+
10
+ /**
11
+ * @var LP_Course_CURD
12
+ */
13
+ protected $course_curd = null;
14
+
15
+ /**
16
+ * @var LP_Section_CURD
17
+ */
18
+ protected $section_curd = null;
19
+
20
+ /**
21
+ * @var LP_Course
22
+ */
23
+ protected $course = null;
24
+
25
+ /**
26
+ * LP_Admin_Editor_Course constructor.
27
+ */
28
+ public function __construct() {
29
+
30
+ }
31
+
32
+ /**
33
+ * Do the action depending on ajax calls with params
34
+ *
35
+ * @return bool|WP_Error
36
+ */
37
+ public function dispatch() {
38
+ check_ajax_referer( 'learnpress_update_curriculum', 'nonce' );
39
+
40
+ $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
41
+ $course_id = $args['id'];
42
+ $course = learn_press_get_course( $course_id );
43
+
44
+ if ( ! $course ) {
45
+ return false;
46
+ }
47
+
48
+ $this->course = $course;
49
+ $this->course_curd = new LP_Course_CURD();
50
+ $this->section_curd = new LP_Section_CURD( $course_id );
51
+ $this->result = array( $args['type'] );
52
+
53
+ $this->call( $args['type'], array( $args ) );
54
+
55
+ return $this->get_result();
56
+ }
57
+
58
+ /**
59
+ * @param array $args
60
+ *
61
+ * @return bool
62
+ */
63
+ public function draft_course( $args = array() ) {
64
+ $new_course = ! empty( $args['course'] ) ? $args['course'] : false;
65
+ $new_course = json_decode( wp_unslash( $new_course ), true );
66
+
67
+ if ( ! $new_course ) {
68
+ return false;
69
+ }
70
+
71
+ $title = $new_course['title'] ? $new_course['title'] : __( 'New Course', 'learnpress' );
72
+ $content = $new_course['content'] ? $new_course['content'] : '';
73
+
74
+ $args = array(
75
+ 'id' => $this->course->get_id(),
76
+ 'status' => 'draft',
77
+ 'title' => $title,
78
+ 'content' => $content
79
+ );
80
+
81
+ $this->course_curd->create( $args );
82
+
83
+ return true;
84
+ }
85
+
86
+ /**
87
+ * @param array $args
88
+ */
89
+ public function hide_sections( $args ) {
90
+ // get hidden sections id
91
+ $hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
92
+ // update course post meta
93
+ update_post_meta( $this->course->get_id(), '_admin_hidden_sections', $hidden );
94
+ }
95
+
96
+ /**
97
+ * Sort sections
98
+ *
99
+ * @param array $args
100
+ */
101
+ public function sort_sections( $args = array() ) {
102
+ $order = ! empty( $args['order'] ) ? $args['order'] : false;
103
+ $order = json_decode( wp_unslash( $order ), true );
104
+
105
+ if ( ! $order ) {
106
+ return;
107
+ }
108
+
109
+ $this->result = $this->section_curd->sort_sections( $order );
110
+
111
+ // last section
112
+ $last_section_id = end( $order );
113
+ // update final quiz
114
+ $this->section_curd->update_final_quiz( $last_section_id );
115
+ }
116
+
117
+ /**
118
+ * @param array $args
119
+ *
120
+ * @return mixed
121
+ */
122
+ public function update_section( $args = array() ) {
123
+ $section = ! empty( $args['section'] ) ? $args['section'] : false;
124
+ $section = json_decode( wp_unslash( $section ), true );
125
+
126
+ if ( ! $section ) {
127
+ return false;
128
+ }
129
+
130
+ $update = array(
131
+ 'section_id' => $section['id'],
132
+ 'section_name' => $section['title'],
133
+ 'section_description' => $section['description'],
134
+ 'section_order' => $section['order'],
135
+ 'section_course_id' => $section['course_id'],
136
+ );
137
+
138
+ $this->result = $this->section_curd->update( $update );
139
+
140
+ return true;
141
+ }
142
+
143
+ /**
144
+ * @param array $args
145
+ *
146
+ * @return mixed
147
+ */
148
+ public function remove_section( $args = array() ) {
149
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
150
+
151
+ if ( ! $section_id ) {
152
+ return false;
153
+ }
154
+
155
+ $this->section_curd->delete( $section_id );
156
+
157
+ return true;
158
+ }
159
+
160
+ /**
161
+ * @param array $args
162
+ *
163
+ * @return mixed
164
+ */
165
+ public function new_section( $args = array() ) {
166
+ $section_name = ! empty( $args['section_name'] ) ? $args['section_name'] : false;
167
+
168
+ $args = array(
169
+ 'section_course_id' => $this->course->get_id(),
170
+ 'section_description' => '',
171
+ 'section_name' => $section_name,
172
+ 'items' => array(),
173
+ );
174
+
175
+ // create section
176
+ $section = $this->section_curd->create( $args );
177
+
178
+ $this->result = array(
179
+ 'id' => $section['section_id'],
180
+ 'items' => $section['items'],
181
+ 'title' => $section['section_name'],
182
+ 'description' => $section['section_description'],
183
+ 'course_id' => $section['section_course_id'],
184
+ 'order' => $section['section_order'],
185
+ );
186
+
187
+ return true;
188
+ }
189
+
190
+ /**
191
+ * @param array $args
192
+ *
193
+ * @return mixed
194
+ */
195
+ public function update_section_item( $args = array() ) {
196
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
197
+ $item = ! empty( $args['item'] ) ? $args['item'] : false;
198
+ $item = json_decode( wp_unslash( $item ), true );
199
+
200
+ if ( ! ( $section_id && $item ) ) {
201
+ return func_get_args();
202
+ }
203
+
204
+ // update lesson, quiz title
205
+ $this->result = $this->section_curd->update_item( $item );
206
+
207
+ return true;
208
+ }
209
+
210
+ /**
211
+ * @param array $args
212
+ *
213
+ * @return mixed
214
+ */
215
+ public function remove_section_item( $args = array() ) {
216
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
217
+ $item_id = ! empty( $args['item_id'] ) ? $args['item_id'] : false;
218
+
219
+ if ( ! ( $section_id && $item_id ) ) {
220
+ return false;
221
+ }
222
+
223
+ // remove item from course
224
+ $this->course_curd->remove_item( $item_id );
225
+
226
+ return true;
227
+ }
228
+
229
+ /**
230
+ * @param array $args
231
+ *
232
+ * @return mixed
233
+ */
234
+ public function delete_section_item( $args = array() ) {
235
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
236
+ $item_id = ! empty( $args['item_id'] ) ? $args['item_id'] : false;
237
+
238
+ if ( ! ( $section_id && $item_id ) ) {
239
+ return false;
240
+ }
241
+
242
+ $this->result = wp_delete_post( $item_id );
243
+
244
+ return true;
245
+ }
246
+
247
+ /**
248
+ * @param array $args
249
+ *
250
+ * @return array|bool
251
+ */
252
+ public function new_section_item( $args = array() ) {
253
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
254
+ $item = ! empty( $args['item'] ) ? $args['item'] : false;
255
+ $item = json_decode( wp_unslash( $item ), true );
256
+
257
+ if ( ! ( $section_id && $item ) ) {
258
+ return false;
259
+ }
260
+
261
+ // create new lesson, quiz and add to course
262
+ $this->result = $this->section_curd->new_item( $section_id, $item );
263
+
264
+ return true;
265
+ }
266
+
267
+ /**
268
+ * @param array $args
269
+ *
270
+ * @return mixed
271
+ */
272
+ public function update_section_items( $args = array() ) {
273
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
274
+ $last_section = ! empty( $args['last_section'] ) ? $args['last_section'] : false;
275
+ $items = ! empty( $args['items'] ) ? $args['items'] : false;
276
+ $items = json_decode( wp_unslash( $items ), true );
277
+
278
+ if ( ! ( $section_id && $items ) ) {
279
+ return false;
280
+ }
281
+
282
+ $this->result = $this->section_curd->update_section_items( $section_id, $items );
283
+
284
+ if ( $last_section ) {
285
+ $this->section_curd->update_final_quiz( $section_id );
286
+ }
287
+
288
+ return true;
289
+ }
290
+
291
+ /**
292
+ * @param array $args
293
+ *
294
+ * @return mixed
295
+ */
296
+ public function search_items( $args = array() ) {
297
+ $query = isset( $args['query'] ) ? $args['query'] : '';
298
+ $type = isset( $args['item_type'] ) ? $args['item_type'] : '';
299
+ $page = ! empty( $args['page'] ) ? $args['page'] : 1;
300
+ $exclude = ! empty( $args['exclude'] ) ? $args['exclude'] : '';
301
+
302
+ if ( $exclude ) {
303
+ $exclude = json_decode( $exclude, true );
304
+ }
305
+
306
+ $ids_exclude = array();
307
+
308
+ if ( is_array( $exclude ) ) {
309
+ foreach ( $exclude as $item ) {
310
+ $ids_exclude[] = $item['id'];
311
+ }
312
+ }
313
+
314
+ $search = new LP_Modal_Search_Items( array(
315
+ 'type' => $type,
316
+ 'context' => 'course',
317
+ 'context_id' => $this->course->get_id(),
318
+ 'term' => $query,
319
+ 'limit' => apply_filters( 'learn-press/course-editor/choose-items-limit', 10 ),
320
+ 'paged' => $page,
321
+ 'exclude' => $ids_exclude,
322
+ ) );
323
+
324
+ $id_items = $search->get_items();
325
+
326
+ $items = array();
327
+ foreach ( $id_items as $id ) {
328
+ $post = get_post( $id );
329
+
330
+ $items[] = array(
331
+ 'id' => $post->ID,
332
+ 'title' => $post->post_title,
333
+ 'type' => $post->post_type,
334
+ );
335
+ }
336
+
337
+ $this->result = array(
338
+ 'items' => $items,
339
+ 'pagination' => $search->get_pagination( false )
340
+ );
341
+
342
+ return true;
343
+ }
344
+
345
+ /**
346
+ * @param array $args
347
+ *
348
+ * @return mixed
349
+ */
350
+ public function add_items_to_section( $args = array() ) {
351
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
352
+ $items = ! empty( $args['items'] ) ? $args['items'] : false;
353
+ $items = json_decode( wp_unslash( $items ), true );
354
+
355
+ if ( ! $items || ! $section_id ) {
356
+ return false;
357
+ }
358
+
359
+ $this->result = $this->section_curd->add_items_section( $section_id, $items );
360
+
361
+ return true;
362
+ }
363
+ }
inc/admin/editor/class-lp-admin-editor-question.php ADDED
@@ -0,0 +1,255 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Admin_Editor_Question
5
+ *
6
+ * @since 3.0.2
7
+ */
8
+ class LP_Admin_Editor_Question extends LP_Admin_Editor {
9
+
10
+ /**
11
+ * @var LP_Question
12
+ */
13
+ protected $question = null;
14
+
15
+ /**
16
+ * @var LP_Question_CURD
17
+ */
18
+ protected $question_curd = null;
19
+
20
+ /**
21
+ * LP_Admin_Editor_Question constructor.
22
+ */
23
+ public function __construct() {
24
+ }
25
+
26
+ public function dispatch() {
27
+ check_ajax_referer( 'learnpress_admin_question_editor', 'nonce' );
28
+
29
+ $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
30
+ $question_id = $args['id'];
31
+ $question = LP_Question::get_question( $question_id );
32
+
33
+ if ( ! $question ) {
34
+ return false;
35
+ }
36
+
37
+ $this->question = $question;
38
+ $this->question_curd = new LP_Question_CURD();
39
+ $this->result = array( 'status' => false );
40
+
41
+ $this->call( $args['type'], array( $args ) );
42
+
43
+ return $this->get_result();
44
+ }
45
+
46
+ /**
47
+ * Get question data in admin question editor.
48
+ *
49
+ * @since 3.0.0
50
+ *
51
+ * @param $question
52
+ * @param $object | if true, input in question object, do not need init LP_Question::get_question()
53
+ *
54
+ * @return array
55
+ */
56
+ public function get_question_data_to_question_editor( $question, $object = false ) {
57
+
58
+ if ( ! $object ) {
59
+ if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
60
+ return array();
61
+ }
62
+
63
+ // get question
64
+ $question = LP_Question::get_question( $question );
65
+ }
66
+
67
+ // question id
68
+ $question_id = $question->get_id();
69
+
70
+ $data = array(
71
+ 'id' => $question_id,
72
+ 'open' => false,
73
+ 'title' => get_the_title( $question_id ),
74
+ 'type' => array(
75
+ 'key' => $question->get_type(),
76
+ 'label' => $question->get_type_label()
77
+ ),
78
+ 'answers' => is_array( $question->get_data( 'answer_options' ) ) ? array_values( $question->get_data( 'answer_options' ) ) : array()
79
+ );
80
+
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Draft question.
86
+ *
87
+ * @since 3.0.0
88
+ *
89
+ * @param $question_id
90
+ * @param array $args
91
+ *
92
+ * @return bool|int|LP_Question
93
+ */
94
+ private function draft_question( $question_id, $args = array() ) {
95
+
96
+ if ( get_post_status( $question_id ) != 'auto-draft' ) {
97
+ return false;
98
+ }
99
+
100
+ $curd = new LP_Question_CURD();
101
+
102
+ $args = wp_parse_args( $args, array(
103
+ 'id' => $question_id,
104
+ 'title' => __( 'New Question', 'learnpress' ),
105
+ 'content' => '',
106
+ 'status' => 'draft',
107
+ 'create_answers' => false
108
+ ) );
109
+
110
+ $question = $curd->create( $args );
111
+
112
+ if ( ! $question ) {
113
+ return false;
114
+ }
115
+
116
+ return $question;
117
+ }
118
+
119
+ /**
120
+ * @param array $args
121
+ *
122
+ * @return bool
123
+ */
124
+ public function change_question_type( $args = array() ) {
125
+ $type = ! empty( $args['question_type'] ) ? $args['question_type'] : false;
126
+
127
+ if ( ! $type ) {
128
+ return false;
129
+ }
130
+
131
+ $question = $this->question;
132
+ // draft question args
133
+ $args = $args['draft_question'] ? $args['draft_question'] : '';
134
+
135
+ if ( $args ) {
136
+ $args = (array) ( json_decode( wp_unslash( $args ), '' ) );
137
+ $draft = $this->draft_question( $this->question->get_id(), $args );
138
+
139
+ // check if draft question false or question exist
140
+ if ( $draft ) {
141
+ $question = $draft;
142
+ }
143
+ }
144
+
145
+ if ( isset( $question ) ) {
146
+ // change question type
147
+ $question = $this->question_curd->change_question_type( $question, $type );
148
+ $this->result = $this->get_question_data_to_question_editor( $question, true );
149
+
150
+ return true;
151
+ }
152
+
153
+ return false;
154
+ }
155
+
156
+ /**
157
+ * @param array $args
158
+ *
159
+ * @return bool
160
+ */
161
+ public function sort_answer( $args = array() ) {
162
+ // answers order
163
+ $order = ! empty( $args['order'] ) ? $args['order'] : false;
164
+
165
+ if ( ! $order ) {
166
+ return false;
167
+ }
168
+
169
+ // sort answers
170
+ $this->question = $this->question_curd->sort_answers( $this->question->get_id(), $order );
171
+
172
+ $this->result = array_values( $this->question->get_data( 'answer_options' ) );
173
+
174
+ return true;
175
+ }
176
+
177
+ /**
178
+ * @param array $args
179
+ *
180
+ * @return bool
181
+ */
182
+ public function update_answer_title( $args = array() ) {
183
+ // answers
184
+ $answer = ! empty( $args['answer'] ) ? $args['answer'] : false;
185
+ $answer = json_decode( wp_unslash( $answer ), true );
186
+
187
+ if ( ! $answer ) {
188
+ return false;
189
+ }
190
+
191
+ // update answer title
192
+ $this->result = $this->question_curd->update_answer_title( $this->question->get_id(), $answer );
193
+
194
+ return true;
195
+ }
196
+
197
+ /**
198
+ * @param array $args
199
+ *
200
+ * @return bool
201
+ */
202
+ public function change_correct( $args = array() ) {
203
+ // correct answer
204
+ $correct = ! empty( $args['correct'] ) ? $args['correct'] : false;
205
+ $correct = json_decode( wp_unslash( $correct ), true );
206
+
207
+ if ( ! $correct ) {
208
+ return false;
209
+ }
210
+
211
+ // update correct answer
212
+ $this->question = $this->question_curd->change_correct_answer( $this->question, $correct );
213
+
214
+ $this->result = $this->question->get_data( 'answer_options' );
215
+
216
+ return true;
217
+ }
218
+
219
+ /**
220
+ * @param array $args
221
+ *
222
+ * @return bool
223
+ */
224
+ public function delete_answer( $args = array() ) {
225
+ // answer id
226
+ $answer_id = ! empty( $args['answer_id'] ) ? $args['answer_id'] : false;
227
+
228
+ if ( ! $answer_id ) {
229
+ return false;
230
+ }
231
+
232
+ // delete answer
233
+ $this->question_curd->delete_answer( $this->question->get_id(), $answer_id );
234
+
235
+ $this->result = $this->question->get_data( 'answer_options' );
236
+
237
+ return true;
238
+ }
239
+
240
+ /**
241
+ * @param array $args
242
+ *
243
+ * @return bool
244
+ */
245
+ public function new_answer( $args = array() ) {
246
+ // new answer
247
+ $answer = LP_Question::get_default_answer();
248
+ // add new
249
+ $this->question_curd->new_answer( $this->question->get_id(), $answer );
250
+
251
+ $this->result = $this->question->get_data( 'answer_options' );
252
+
253
+ return true;
254
+ }
255
+ }
inc/admin/editor/class-lp-admin-editor-quiz.php ADDED
@@ -0,0 +1,594 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Admin_Editor_Quiz
5
+ *
6
+ * @since 3.0.2
7
+ */
8
+ class LP_Admin_Editor_Quiz extends LP_Admin_Editor {
9
+
10
+ /**
11
+ * @var LP_Quiz_CURD
12
+ */
13
+ protected $quiz_curd = null;
14
+
15
+ /**
16
+ * @var LP_Question_CURD
17
+ */
18
+ protected $question_curd = null;
19
+
20
+ /**
21
+ * @var LP_Quiz
22
+ */
23
+ protected $quiz = null;
24
+
25
+ /**
26
+ * LP_Admin_Editor_Quiz constructor.
27
+ */
28
+ public function __construct() {
29
+ }
30
+
31
+ /**
32
+ * Do the action depending on ajax calls with params
33
+ *
34
+ * @return bool|mixed|WP_Error
35
+ */
36
+ public function dispatch() {
37
+ check_ajax_referer( 'learnpress_admin_quiz_editor', 'nonce' );
38
+ $args = wp_parse_args( $_REQUEST, array( 'id' => false, 'type' => '' ) );
39
+
40
+ // get quiz
41
+ $quiz_id = $args['id'];
42
+ $quiz = learn_press_get_quiz( $quiz_id );
43
+
44
+ if ( ! $quiz ) {
45
+ return new WP_Error( 'INVALID_QUIZ', __( 'Invalid quiz', 'learnpress' ) );
46
+ }
47
+
48
+ $this->quiz = $quiz;
49
+ $this->quiz_curd = new LP_Quiz_CURD();
50
+ $this->question_curd = new LP_Question_CURD();
51
+ $this->result = array( 'status' => false );
52
+
53
+ $this->call( $args['type'], array( $args ) );
54
+
55
+ return $this->get_result();
56
+ }
57
+
58
+ /**
59
+ * Get question data in admin quiz editor.
60
+ *
61
+ * @since 3.0.0
62
+ *
63
+ * @param $question
64
+ * @param $object | if true, input in question object, do not need init LP_Question::get_question()
65
+ * @param array $args
66
+ *
67
+ * @return array
68
+ */
69
+ public function get_question_data_to_quiz_editor( $question, $object = false, $args = array() ) {
70
+
71
+ if ( ! $object ) {
72
+ if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
73
+ return array();
74
+ }
75
+
76
+ // get question
77
+ $question = LP_Question::get_question( $question );
78
+ }
79
+
80
+ // question id
81
+ $question_id = $question->get_id();
82
+ // question answer
83
+ $answers = array_values( $question->get_data( 'answer_options' ) );
84
+
85
+ $data = wp_parse_args( $args, array(
86
+ 'id' => $question_id,
87
+ 'open' => false,
88
+ 'title' => get_the_title( $question_id ),
89
+ 'type' => array(
90
+ 'key' => $question->get_type(),
91
+ 'label' => $question->get_type_label()
92
+ ),
93
+ 'answers' => $answers,
94
+ 'settings' => array(
95
+ 'mark' => get_post_meta( $question_id, '_lp_mark', true ),
96
+ 'explanation' => get_post_meta( $question_id, '_lp_explanation', true ),
97
+ 'hint' => get_post_meta( $question_id, '_lp_hint', true )
98
+ ),
99
+ 'order' => count( $answers )
100
+ ) );
101
+
102
+ return $data;
103
+ }
104
+
105
+ /**
106
+ * @param array $args
107
+ *
108
+ * @return bool
109
+ */
110
+ public function hidden_questions( $args = array() ) {
111
+ $hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
112
+ update_post_meta( $this->quiz->get_id(), '_lp_hidden_questions', $hidden );
113
+
114
+ return true;
115
+ }
116
+
117
+ /**
118
+ * @param array $args
119
+ *
120
+ * @return bool
121
+ */
122
+ public function new_question( $args = array() ) {
123
+ // new question
124
+ $question = ! empty( $args['question'] ) ? $args['question'] : false;
125
+ $question = json_decode( wp_unslash( $question ), true );
126
+
127
+ if ( ! $question ) {
128
+ return false;
129
+ }
130
+
131
+ $quiz_id = $this->quiz->get_id();
132
+
133
+ // draft quiz
134
+ if ( get_post_status( $quiz_id ) == 'auto-draft' ) {
135
+
136
+ $draft_quiz = ! empty( $args['draft_quiz'] ) ? $args['draft_quiz'] : '';
137
+ $draft_quiz = (array) ( json_decode( wp_unslash( $draft_quiz ), '' ) );
138
+
139
+ $quiz_args = array(
140
+ 'id' => $this->quiz->get_id(),
141
+ 'title' => $draft_quiz['title'] ? $draft_quiz['title'] : __( 'New Quiz', 'learnpress' ),
142
+ 'content' => $draft_quiz['content'],
143
+ 'status' => 'draft'
144
+ );
145
+
146
+ $quiz_id = $this->quiz_curd->create( $quiz_args );
147
+ }
148
+
149
+ if ( ! isset( $quiz_id ) ) {
150
+ $this->result = new WP_Error( 'CREATE_QUIZ_FAILED', __( 'Quiz creation failed.', 'learnpress' ) );
151
+
152
+ return false;
153
+ }
154
+
155
+ $args = array(
156
+ 'quiz_id' => $quiz_id,
157
+ 'title' => $question['title'],
158
+ 'type' => $question['type'],
159
+ );
160
+
161
+ $new_question = $this->question_curd->create( $args );
162
+
163
+ if ( ! is_wp_error( $new_question ) ) {
164
+
165
+ // update hidden questions in quiz meta
166
+ $quiz = LP_Quiz::get_quiz( $quiz_id );
167
+ $hidden_questions = $quiz->get_questions();
168
+
169
+ if ( $hidden_questions ) {
170
+ unset( $hidden_questions[ $new_question->get_id() ] );
171
+ $hidden_questions = array_keys( $hidden_questions );
172
+ }
173
+
174
+ update_post_meta( $quiz_id, '_lp_hidden_questions', $hidden_questions );
175
+
176
+ // get new question data
177
+ $this->result = $this->get_question_data_to_quiz_editor( $new_question, true, array( 'open' => true ) );
178
+
179
+ return true;
180
+ }
181
+
182
+ return false;
183
+ }
184
+
185
+ /**
186
+ * @param array $args
187
+ *
188
+ * @return bool
189
+ */
190
+ public function sort_questions( $args = array() ) {
191
+ $order = ! empty( $args['order'] ) ? $args['order'] : false;
192
+ $order = json_decode( wp_unslash( $order ), true );
193
+
194
+ if ( ! $order ) {
195
+ return false;
196
+ }
197
+
198
+ $this->result = $this->quiz_curd->sort_questions( $order );
199
+
200
+ return true;
201
+ }
202
+
203
+ /**
204
+ * @param array $args
205
+ *
206
+ * @return bool
207
+ */
208
+ public function update_question_title( $args = array() ) {
209
+ $question = ! empty( $args['question'] ) ? $args['question'] : false;
210
+ $question = json_decode( wp_unslash( $question ), true );
211
+
212
+ if ( ! $question ) {
213
+ return false;
214
+ }
215
+
216
+ wp_update_post( array( 'ID' => $question['id'], 'post_title' => $question['title'] ) );
217
+
218
+ $this->result['status'] = true;
219
+
220
+ return true;
221
+ }
222
+
223
+ /**
224
+ * @param array $args
225
+ *
226
+ * @return bool
227
+ */
228
+ public function change_question_type( $args = array() ) {
229
+ $question_id = ! empty( $args['question_id'] ) ? $args['question_id'] : false;
230
+ $type = ! empty( $args['question_type'] ) ? $args['question_type'] : false;
231
+
232
+ if ( ! ( $question_id || $type ) ) {
233
+ return false;
234
+ }
235
+
236
+ $question = LP_Question::get_question( $question_id );
237
+
238
+ // change question type
239
+ $question = $this->question_curd->change_question_type( $question, $type );
240
+
241
+ $this->result = $this->get_question_data_to_quiz_editor( $question, true );
242
+
243
+ return true;
244
+ }
245
+
246
+ /**
247
+ * @param array $args
248
+ *
249
+ * @return bool
250
+ */
251
+ public function clone_question( $args = array() ) {
252
+ $question = ! empty( $args['question'] ) ? $args['question'] : false;
253
+ $question = json_decode( wp_unslash( $question ), true );
254
+
255
+ if ( ! $question ) {
256
+ return false;
257
+ }
258
+
259
+ // duplicate question
260
+ $new_question_id = $this->question_curd->duplicate( $question['id'], array( 'post_status' => 'publish' ) );
261
+
262
+ if ( ! is_wp_error( $new_question_id ) ) {
263
+
264
+ // add question to hidden questions in quiz meta
265
+ $hidden_questions = get_post_meta( $this->quiz->get