PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.10
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.10
4.4.10 4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 All 142 releases
learnpress / inc / Ajax / EditQuestionAjax.php

EditQuestionAjax.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.10, at inc/Ajax/EditQuestionAjax.php

320 lines 9.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * class EditCurriculumAjax
4 *
5 * This class handles the AJAX request to edit the curriculum of a course.
6 *
7 * @since 4.2.9
8 * @version 1.0.2
9 */
10
11 namespace LearnPress\Ajax;
12
13 use Exception;
14 use LearnPress\Ajax\AbstractAjax;
15
16 use LearnPress\Databases\QuestionAnswersDB;
17 use LearnPress\Helpers\Template;
18 use LearnPress\Models\Question\QuestionAnswerModel;
19 use LearnPress\Models\Question\QuestionPostFIBModel;
20 use LearnPress\Models\Question\QuestionPostModel;
21 use LearnPress\Models\Question\QuestionPostMultipleChoiceModel;
22 use LearnPress\Models\Question\QuestionPostSingleChoiceModel;
23 use LearnPress\Models\Question\QuestionSortingChoiceModel;
24 use LearnPress\TemplateHooks\Admin\AdminEditQuestionTemplate;
25 use LP_Helper;
26 use LP_REST_Response;
27 use Throwable;
28
29 class EditQuestionAjax extends AbstractAjax {
30 /**
31 * Check permissions and validate parameters.
32 *
33 * @throws Exception
34 *
35 * @since 4.2.9
36 * @version 1.0.0
37 */
38 public static function check_valid() {
39 $params = wp_unslash( $_REQUEST['data'] ?? '' );
40 if ( empty( $params ) ) {
41 throw new Exception( 'Error: params invalid!' );
42 }
43
44 $params = LP_Helper::json_decode( $params, true );
45 $question_id = $params['question_id'] ?? 0;
46 $questionPostModel = QuestionPostModel::find( $question_id, true );
47 if ( ! $questionPostModel ) {
48 throw new Exception( __( 'Question not found', 'learnpress' ) );
49 }
50
51 $params['questionPostModel'] = $questionPostModel;
52
53 return $params;
54 }
55
56 /**
57 * Update question title.
58 *
59 * JS file edit-quiz.js: function updateQuestionTitle call this method.
60 *
61 * @since 4.2.9
62 * @version 1.0.1
63 */
64 public static function update_question() {
65 $response = new LP_REST_Response();
66
67 try {
68 $data = self::check_valid();
69 $question_id = $data['question_id'] ?? 0;
70 $question_title = $data['question_title'] ?? false;
71 $question_description = $data['question_description'] ?? false;
72 $question_hint = $data['question_hint'] ?? false;
73 $question_explanation = $data['question_explanation'] ?? false;
74 $question_mark = $data['question_mark'] ?? false;
75 $question_type = $data['question_type'] ?? false;
76
77 $questionPostModel = QuestionPostModel::find( $question_id, true );
78 if ( ! $questionPostModel ) {
79 throw new Exception( __( 'Question not found', 'learnpress' ) );
80 }
81
82 if ( false !== $question_title ) {
83 if ( empty( $question_title ) ) {
84 throw new Exception( __( 'Question title is required', 'learnpress' ) );
85 }
86
87 $questionPostModel->post_title = $question_title;
88 }
89
90 if ( false !== $question_description ) {
91 $questionPostModel->post_content = $question_description;
92 }
93
94 if ( false !== $question_hint ) {
95 $question_hint = Template::sanitize_html_content( $question_hint );
96 $questionPostModel->save_meta_value_by_key( QuestionPostModel::META_KEY_HINT, $question_hint );
97 }
98
99 if ( false !== $question_explanation ) {
100 $question_explanation = Template::sanitize_html_content( $question_explanation );
101 $questionPostModel->save_meta_value_by_key( QuestionPostModel::META_KEY_EXPLANATION, $question_explanation );
102 }
103
104 if ( false !== $question_mark ) {
105 $question_mark = (float) $question_mark;
106 $questionPostModel->save_meta_value_by_key( QuestionPostModel::META_KEY_MARK, $question_mark );
107 }
108
109 if ( false !== $question_type ) {
110 $question_type = LP_Helper::sanitize_params_submitted( $question_type, 'key' );
111
112 if ( ! in_array( $question_type, array_keys( QuestionPostModel::get_types() ), true ) ) {
113 throw new Exception( __( 'Invalid question type', 'learnpress' ) );
114 }
115
116 $questionPostModel->save_meta_value_by_key( QuestionPostModel::META_KEY_TYPE, $question_type );
117
118 // Create default answers for question
119 $questionClassName = $questionPostModel::get_question_obj_by_type( $question_type );
120 if ( class_exists( $questionClassName ) ) {
121 $questionPostTyeModel = new $questionClassName( $questionPostModel );
122 if ( method_exists( $questionPostTyeModel, 'create_default_answers' ) ) {
123 $questionPostTyeModel->create_default_answers();
124 }
125 } else {
126 throw new Exception( __( 'Question type not found', 'learnpress' ) );
127 }
128
129 $response->data->html_option_answers = AdminEditQuestionTemplate::instance()->html_answer_option(
130 $questionPostModel
131 );
132 }
133
134 $questionPostModel->save();
135 $response->status = 'success';
136 $response->message = __( 'Question update successfully', 'learnpress' );
137 } catch ( Throwable $e ) {
138 $response->message = $e->getMessage();
139 }
140
141 wp_send_json( $response );
142 }
143
144 /**
145 * Update answer config of question
146 *
147 * JS file edit-quiz.js: function addQuestionAnswer call this method.
148 *
149 * @return void
150 */
151 public static function add_question_answer() {
152 $response = new LP_REST_Response();
153
154 try {
155 $data = self::check_valid();
156 $answer_title = Template::sanitize_html_content( $data['answer_title'] ?? '' );
157 if ( empty( $answer_title ) ) {
158 throw new Exception( __( 'Answer title is required', 'learnpress' ) );
159 }
160
161 /**
162 * @var QuestionPostModel $questionPostModel
163 */
164 $questionPostModel = $data['questionPostModel'];
165 $type = $questionPostModel->get_type();
166
167 if ( $type === 'single_choice' ) {
168 $questionAnswerModel = new QuestionPostSingleChoiceModel( $questionPostModel );
169 } elseif ( $type === 'multiple_choice' ) {
170 $questionAnswerModel = new QuestionPostMultipleChoiceModel( $questionPostModel );
171 } else {
172
173 }
174
175 $db = QuestionAnswersDB::getInstance();
176 $max_order = $db->get_last_number_order( $questionPostModel->get_id() );
177
178 $answer = array(
179 'question_id' => $questionPostModel->get_id(),
180 'title' => $answer_title,
181 'value' => learn_press_random_value(),
182 'is_true' => $answer['is_true'] ?? '',
183 'order' => $max_order + 1,
184 );
185
186 $questionAnswerModel = new QuestionAnswerModel( $answer );
187 $questionAnswerModel->save();
188
189 $response->status = 'success';
190 $response->data->question_answer = $questionAnswerModel;
191 $response->message = __( 'Question answer added successfully', 'learnpress' );
192 } catch ( Throwable $e ) {
193 $response->message = $e->getMessage();
194 }
195
196 wp_send_json( $response );
197 }
198
199 /**
200 * Update answer config of question
201 *
202 * JS file edit-question.js: function fibSaveContent call this method.
203 *
204 * @return void
205 */
206 public function update_question_answers_config() {
207 $response = new LP_REST_Response();
208
209 try {
210 $data = self::check_valid();
211 $question_id = $data['question_id'] ?? 0;
212 $question_answers = $data['answers'] ?? [];
213 $question_answers = LP_Helper::sanitize_params_submitted( $question_answers, 'html', false );
214
215 $questionPostModel = QuestionPostModel::find( $question_id, true );
216 if ( ! $questionPostModel ) {
217 throw new Exception( __( 'Question not found', 'learnpress' ) );
218 }
219
220 if ( $questionPostModel->get_type() === 'fill_in_blanks' ) {
221 $questionPostFIBModel = new QuestionPostFIBModel( $questionPostModel );
222 // Update title
223 $questionAnswerModel = new QuestionAnswerModel( $question_answers );
224 $content = $question_answers['title'] ?? '';
225 $meta_data = $question_answers['meta_data'] ?? [];
226 $questionAnswerModel->title = $questionPostFIBModel->convert_content_from_editor_to_db( $content );
227 $questionAnswerModel->save();
228 // Update meta value for fill in blanks
229 $pattern = '#<span class="lp-question-fib-input" data-id="([^"]+)">([^<]+)<\/span>#';
230 preg_match_all( $pattern, $content, $matches );
231 $ids = [];
232
233 $fib_blank_options = [];
234 if ( ! empty( $matches ) ) {
235 $ids = $matches[1];
236 $fills = $matches[2];
237
238 foreach ( $ids as $index => $id ) {
239 $fib_blank_options[ $id ] = [
240 'id' => $id,
241 'fill' => html_entity_decode( $fills[ $index ] ?? '' ),
242 'match_case' => 0,
243 'comparison' => 'equal',
244 ];
245 }
246 }
247
248 if ( ! empty( $meta_data ) ) {
249 foreach ( $meta_data as $blank_id => $blank_options ) {
250 if ( $meta_data[ $blank_id ]['comparison'] === '' ) {
251 $meta_data[ $blank_id ]['comparison'] = 'equal';
252 }
253
254 if ( ! in_array( $blank_id, $ids, true ) ) {
255 unset( $meta_data[ $blank_id ] );
256 }
257 }
258 }
259
260 // If not null ids, but meta_data is empty, we will set default options for blanks.
261 if ( ! empty( $ids ) && empty( $meta_data ) ) {
262 $meta_data = $fib_blank_options;
263 }
264
265 $questionAnswerModel->save_meta_value_by_key( QuestionAnswerModel::META_KEY_BLANKS, $meta_data );
266 } else {
267 foreach ( $question_answers as $answer ) {
268 if ( empty( $answer ) ) {
269 continue;
270 }
271
272 $questionAnswerModel = new QuestionAnswerModel( $answer );
273 $questionAnswerModel->save();
274 }
275 }
276
277 $response->status = 'success';
278 $response->message = __( 'Answer of Question update successfully', 'learnpress' );
279 } catch ( Throwable $e ) {
280 $response->message = $e->getMessage();
281 }
282
283 wp_send_json( $response );
284 }
285
286 /**
287 * Delete answer of question
288 *
289 * JS file edit-quiz.js: function deleteQuestionAnswer call this method.
290 *
291 * @return void
292 */
293 public static function delete_question_answer() {
294 $response = new LP_REST_Response();
295
296 try {
297 $data = self::check_valid();
298 $question_answer_id = $data['question_answer_id'] ?? '';
299 if ( empty( $question_answer_id ) ) {
300 throw new Exception( __( 'Invalid request!', 'learnpress' ) );
301 }
302
303 $questionAnswerModel = QuestionAnswerModel::find( $question_answer_id, true );
304 if ( ! $questionAnswerModel ) {
305 throw new Exception( __( 'Question answer not found', 'learnpress' ) );
306 }
307
308 // Delete question answer
309 $questionAnswerModel->delete();
310
311 $response->status = 'success';
312 $response->message = __( 'Question answer deleted successfully', 'learnpress' );
313 } catch ( Throwable $e ) {
314 $response->message = $e->getMessage();
315 }
316
317 wp_send_json( $response );
318 }
319 }
320