PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.9
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 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / WPGDPR / ExportPersonalData.php

ExportPersonalData.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.9, at inc/WPGDPR/ExportPersonalData.php

609 lines 18.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace LearnPress\WPGDPR;
3
4 use Exception;
5 use LearnPress\Helpers\Singleton;
6 use LearnPress\Models\UserItems\UserCourseModel;
7 use LearnPress\Models\CourseModel;
8 use LearnPress\Models\UserModel;
9 use LP_Post_DB;
10 use LP_Order_Filter;
11 use LP_User_Items_Filter;
12 use LP_User_Items_DB;
13 use LP_Datetime;
14 use LP_Course_DB;
15 use LP_Course_Filter;
16
17 /**
18 * Class ExportPersonalData
19 *
20 * @since 4.2.9.4
21 * @version 1.0.0
22 */
23 class ExportPersonalData {
24
25 use Singleton;
26
27 public function init() {
28 add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporters' ), 6 );
29 }
30
31 public function register_exporters( $exporters ) {
32 $exporters['learnpress-user-meta'] = array(
33 'exporter_friendly_name' => __( 'LearnPress User Meta Data Exporter', 'learnpress' ),
34 'callback' => array( $this, 'export_user_meta' ),
35 );
36 $exporters['learnpress-created-courses'] = array(
37 'exporter_friendly_name' => __( 'LearnPress Created Courses Data Exporter', 'learnpress' ),
38 'callback' => array( $this, 'export_user_created_courses' ),
39 );
40 $exporters['learnpress-attended-courses'] = array(
41 'exporter_friendly_name' => __( 'LearnPress Attended Courses Data Exporter', 'learnpress' ),
42 'callback' => array( $this, 'export_user_attended_courses' ),
43 );
44 $exporters['learnpress-orders'] = array(
45 'exporter_friendly_name' => __( 'LearnPress Orders Data Exporter', 'learnpress' ),
46 'callback' => array( $this, 'export_user_orders' ),
47 );
48 return $exporters;
49 }
50
51 public function export_user_meta( $email, $page = 1 ) {
52 $export_items = array();
53
54 $user = get_user_by( 'email', $email );
55 if ( $user ) {
56 $user_id = $user->ID;
57 $data = array();
58 $userModel = UserModel::find( $user_id, true );
59
60 if ( $userModel->is_instructor() ) {
61 $instructor_statistic = $userModel->get_instructor_statistic();
62 $data = $this->map_instructor_statistics( $instructor_statistic, $data );
63 }
64 $student_statistic = $userModel->get_student_statistic();
65 $data = $this->map_student_statistics( $student_statistic, $data );
66
67 $social_fields = learn_press_social_profiles();
68 $socials = learn_press_get_user_extra_profile_info( $user_id );
69 foreach ( $socials as $key => $value ) {
70 if ( ! empty( $value ) && isset( $social_fields[ $key ] ) ) {
71 $data[] = array(
72 'name' => $social_fields[ $key ],
73 'value' => $value,
74 );
75 }
76 }
77 $export_items[] = array(
78 'group_id' => 'learnpress-user-meta',
79 'group_label' => __( 'LearnPress Profile Info', 'learnpress' ),
80 'group_description' => __( 'User&#8217;s LearnPress User Profile Data.', 'learnpress' ),
81 'item_id' => 'user_id-' . $user_id,
82 'data' => $data,
83 );
84 }
85
86 return array(
87 'data' => $export_items,
88 'done' => true,
89 );
90 }
91
92 /**
93 * Map instructor statistics to exportable data
94 *
95 * @param array $statistic
96 * @param array $data
97 *
98 * @return array
99 */
100 public function map_instructor_statistics( array $statistic, array $data ): array {
101 foreach ( $statistic as $key => $value ) {
102 switch ( $key ) {
103 case 'total_course':
104 $data[] = array(
105 'name' => __( 'Total Course', 'learnpress' ),
106 'value' => $value,
107 );
108 break;
109 case 'published_course':
110 $data[] = array(
111 'name' => __( 'Published Course', 'learnpress' ),
112 'value' => $value,
113 );
114 break;
115 case 'pending_course':
116 $data[] = array(
117 'name' => __( 'Pending Course', 'learnpress' ),
118 'value' => $value,
119 );
120 break;
121 case 'total_student':
122 $data[] = array(
123 'name' => __( 'Total Student', 'learnpress' ),
124 'value' => $value,
125 );
126 break;
127 case 'student_completed':
128 $data[] = array(
129 'name' => __( 'Student Completed', 'learnpress' ),
130 'value' => $value,
131 );
132 break;
133 case 'student_in_progress':
134 $data[] = array(
135 'name' => __( 'Student In-progress', 'learnpress' ),
136 'value' => $value,
137 );
138 break;
139 }
140 }
141 return $data;
142 }
143
144 /**
145 * Map student statistics to exportable data
146 *
147 * @param array $statistic
148 * @param array $data
149 *
150 * @return array
151 */
152 public function map_student_statistics( array $statistic, array $data ): array {
153 foreach ( $statistic as $key => $value ) {
154 if ( $value ) {
155 switch ( $key ) {
156 case 'enrolled_courses':
157 $data[] = array(
158 'name' => __( 'Enrolled Course', 'learnpress' ),
159 'value' => $value,
160 );
161 break;
162 case 'in_progress_course':
163 $data[] = array(
164 'name' => __( 'Inprogress Course', 'learnpress' ),
165 'value' => $value,
166 );
167 break;
168 case 'finished_courses':
169 $data[] = array(
170 'name' => __( 'Finished Course', 'learnpress' ),
171 'value' => $value,
172 );
173 break;
174 case 'passed_courses':
175 $data[] = array(
176 'name' => __( 'Passed Course', 'learnpress' ),
177 'value' => $value,
178 );
179 break;
180 case 'failed_courses':
181 $data[] = array(
182 'name' => __( 'Failed Course', 'learnpress' ),
183 'value' => $value,
184 );
185 break;
186 }
187 }
188 }
189
190 return $data;
191 }
192
193 /**
194 * Export user attended courses data
195 *
196 * @param string $email
197 * @param int $page
198 *
199 * @return array
200 * @throws Exception
201 */
202 public function export_user_attended_courses( $email, $page = 1 ) {
203 $export_items = array();
204 $done = true;
205 $user = get_user_by( 'email', $email );
206 if ( $user ) {
207 $user_id = $user->ID;
208 $lpuidb = LP_User_Items_DB::getInstance();
209
210 $ui_filter = new LP_User_Items_Filter();
211 $ui_filter->user_id = $user_id;
212 $ui_filter->item_type = LP_COURSE_CPT;
213 $ui_filter->only_fields = array( 'DISTINCT (item_id) AS item_id', 'ui.user_item_id' );
214 $ui_filter->field_count = 'ui.item_id';
215 $ui_filter->limit = 10;
216 $ui_filter->page = $page ?? 1;
217 $lp_ui_ids = $lpuidb->get_user_items( $ui_filter );
218 if ( ! empty( $lp_ui_ids ) ) {
219 foreach ( $lp_ui_ids as $useritem ) {
220 $export_items[] = array(
221 'group_id' => 'learnpress-attended-courses',
222 'group_label' => __( 'LearnPress Attended Courses', 'learnpress' ),
223 'group_description' => __( 'User&#8217;s LearnPress Attended Courses Data.', 'learnpress' ),
224 'item_id' => 'user_item_id-' . $useritem->item_id,
225 'data' => $this->get_user_course_personal_data( $useritem, $user_id ),
226 );
227 }
228 }
229 $done = 10 > count( $lp_ui_ids );
230 }
231
232 return array(
233 'data' => $export_items,
234 'done' => $done,
235 );
236 }
237
238 /**
239 * Get user course personal data
240 *
241 * @param object $useritem
242 * @param int $user_id
243 *
244 * @return array
245 * @throws Exception
246 */
247 protected function get_user_course_personal_data( $useritem, $user_id ) {
248 $data = array();
249 $userCourseModel = UserCourseModel::find( $user_id, $useritem->item_id );
250 $props = apply_filters(
251 'learnpress/export-user-attended-courses-personal-data/props',
252 array(
253 'course_name' => __( 'Course name', 'learnpress' ),
254 'start_time' => __( 'Start time', 'learnpress' ),
255 'end_time' => __( 'End time', 'learnpress' ),
256 'status' => __( 'Status', 'learnpress' ),
257 'result' => __( 'Result', 'learnpress' ),
258 ),
259 $userCourseModel
260 );
261 $date_format = get_option( 'date_format' );
262 foreach ( $props as $prop => $name ) {
263 $value = '';
264 switch ( $prop ) {
265 case 'course_name':
266 $value = get_the_title( $useritem->item_id );
267 break;
268 case 'status':
269 $value = $userCourseModel->is_finished() ? $userCourseModel->get_string_i18n( $userCourseModel->get_graduation() ) : $userCourseModel->get_string_i18n( $userCourseModel->get_status() );
270 break;
271 case 'start_time':
272 $value = wp_date( $date_format, strtotime( $userCourseModel->start_time ) );
273 break;
274 case 'end_time':
275 $value = ! empty( $userCourseModel->end_time ) ? wp_date( $date_format, strtotime( $userCourseModel->end_time ) ) : '-';
276 break;
277 case 'result':
278 $result = $userCourseModel->calculate_course_results();
279 $value = ! empty( $result['result'] ) ? $result['result'] . '%' : '-';
280 break;
281 }
282
283 $value = apply_filters( 'learnpress/export-user-attended-courses-personal-data-prop', $value, $prop, $userCourseModel );
284 if ( $value ) {
285 $data[] = array(
286 'name' => $name,
287 'value' => $value,
288 );
289 }
290 }
291
292 return $data;
293 }
294
295 /**
296 * Export user created courses data
297 *
298 * @param string $email
299 * @param int $page
300 *
301 * @return array
302 * @throws Exception
303 */
304 public function export_user_created_courses( $email, $page = 1 ) {
305 $export_items = array();
306 $done = true;
307 $user = get_user_by( 'email', $email );
308 $userModel = $user ? UserModel::find( $user->ID, true ) : null;
309 if ( $userModel && $userModel->is_instructor() ) {
310 $user_id = $user->ID;
311 $filter = new LP_Course_Filter();
312 $course_db = LP_Course_DB::getInstance();
313 $filter->post_author = $user_id;
314 $filter->only_fields[] = 'p.ID as ID';
315 $filter->limit = 10;
316 $filter->page = (int) $page;
317 $filter->run_query_count = false;
318 $course_ids = $course_db->get_courses( $filter );
319 if ( ! empty( $course_ids ) ) {
320 foreach ( $course_ids as $c ) {
321 $export_items[] = array(
322 'group_id' => 'learnpress-created-courses',
323 'group_label' => __( 'LearnPress Created Courses', 'learnpress' ),
324 'group_description' => __( 'User&#8217;s LearnPress Created Courses Data.', 'learnpress' ),
325 'item_id' => 'course_id-' . $c->ID,
326 'data' => $this->get_user_created_courses_personal_data( $c->ID, $user_id ),
327 );
328 }
329 }
330 $done = 10 > count( $course_ids );
331 }
332
333 return array(
334 'data' => $export_items,
335 'done' => $done,
336 );
337 }
338
339 /**
340 * Get user created courses personal data
341 *
342 * @param int $course_id
343 * @param int $user_id
344 *
345 * @return array
346 * @throws Exception
347 */
348 protected function get_user_created_courses_personal_data( $course_id, $user_id ): array {
349 $data = array();
350 $courseModel = CourseModel::find( $course_id, true );
351 $props = apply_filters(
352 'learn-press/export-user-created-courses-personal-data/props',
353 array(
354 'title' => __( 'Course name', 'learnpress' ),
355 'price' => __( 'Price', 'learnpress' ),
356 'duration' => __( 'Duration', 'learnpress' ),
357 'level' => __( 'Level', 'learnpress' ),
358 'students' => __( 'Total Students', 'learnpress' ),
359 'lp_lesson' => __( 'Lessons', 'learnpress' ),
360 'lp_quiz' => __( 'Quizzes', 'learnpress' ),
361 'lp_assignment' => __( 'Assignments', 'learnpress' ),
362 'lp_h5p' => __( 'H5P Quizzes', 'learnpress' ),
363 ),
364 $courseModel,
365 $user_id
366 );
367 foreach ( $props as $prop => $name ) {
368 $value = '';
369 switch ( $prop ) {
370 case 'lp_lesson':
371 case 'lp_quiz':
372 case 'lp_assignment':
373 case 'lp_h5p':
374 $value = $courseModel->count_items( $prop );
375 break;
376 case 'students':
377 $value = $courseModel->count_students();
378 break;
379 case 'duration':
380 $duration = $courseModel->get_meta_value_by_key( '_lp_duration', '' );
381 $duration_arr = explode( ' ', $duration );
382 $duration_number = floatval( $duration_arr[0] ?? 0 );
383 $duration_type = $duration_arr[1] ?? '';
384 if ( empty( $duration_number ) ) {
385 $value = __( 'Lifetime', 'learnpress' );
386 } else {
387 $value = LP_Datetime::get_string_plural_duration( $duration_number, $duration_type );
388 }
389 break;
390 case 'level':
391 $level = $courseModel->get_meta_value_by_key( '_lp_level', '' );
392 $levels = lp_course_level();
393 $value = $levels[ $level ] ?? $levels['all'];
394 break;
395 case 'price':
396 $value = $courseModel->is_free() ? __( 'Free', 'learnpress' ) : learn_press_format_price( $courseModel->get_price() );
397 break;
398 default:
399 if ( is_callable( array( $courseModel, 'get_' . $prop ) ) ) {
400 $value = $courseModel->{"get_$prop"}();
401 }
402 break;
403 }
404 $value = apply_filters( 'learnpress/export-user-created-courses-personal-data/prop', $value, $prop, $courseModel, $user_id );
405 if ( $value ) {
406 $data[] = array(
407 'name' => $name,
408 'value' => $value,
409 );
410 }
411 }
412
413 return $data;
414 }
415
416 /**
417 * Export user orders data
418 *
419 * @param string $email
420 * @param int $page
421 *
422 * @return array
423 * @throws Exception
424 */
425 public function export_user_orders( $email, $page = 1 ) {
426 $export_items = array();
427 $done = true;
428 $user = get_user_by( 'email', $email );
429 if ( $user ) {
430 $order_data = $this->export_order_via_user( $user, $page );
431 $export_items = $order_data['data'];
432 $done = $order_data['done'];
433 } else {
434 $order_data = $this->export_order_via_email( $email, $page );
435 $export_items = $order_data['data'];
436 $done = $order_data['done'];
437 }
438 return array(
439 'data' => $export_items,
440 'done' => $done,
441 );
442 }
443
444 /**
445 * Export order via user ID
446 *
447 * @param \WP_User $user
448 * @param int $page
449 *
450 * @return array
451 * @throws Exception
452 */
453 public function export_order_via_user( $user, $page = 1 ) {
454 $user_id = $user->ID;
455 $data_to_export = array();
456 $done = true;
457 $lp_postdb = LP_Post_DB::getInstance();
458 $filter = new LP_Order_Filter();
459 $filter->only_fields[] = 'p.ID as ID';
460 $filter->join[] = "INNER JOIN $lp_postdb->tb_postmeta AS pm ON p.ID = pm.post_id";
461 $filter->where = array(
462 $lp_postdb->wpdb->prepare(
463 'AND pm.meta_key=%s AND ( pm.meta_value=%s OR pm.meta_value LIKE %s)',
464 '_user_id',
465 $user_id,
466 '%' . $lp_postdb->wpdb->esc_like( '"' . $user_id . '"' ) . '%'
467 ),
468 );
469 $filter->limit = 10;
470 $filter->page = $page ?? 1;
471 $filter->run_query_count = false;
472 $lp_order_ids = $lp_postdb->get_posts( $filter );
473 if ( ! empty( $lp_order_ids ) ) {
474 $data_to_export = $this->process_order_data( $lp_order_ids );
475 }
476 $done = 10 > count( $lp_order_ids );
477
478 return array(
479 'data' => $data_to_export,
480 'done' => $done,
481 );
482 }
483
484 /**
485 * Export order via email
486 *
487 * @param string $email
488 * @param int $page
489 *
490 * @return array
491 * @throws Exception
492 */
493 public function export_order_via_email( $email, $page = 1 ) {
494 $data_to_export = array();
495 $done = true;
496 $lp_postdb = LP_Post_DB::getInstance();
497 $filter = new LP_Order_Filter();
498 $filter->only_fields[] = 'p.ID as ID';
499 $filter->join[] = "INNER JOIN $lp_postdb->tb_postmeta AS pm ON p.ID = pm.post_id";
500 $filter->where = array(
501 $lp_postdb->wpdb->prepare(
502 'AND pm.meta_key=%s AND pm.meta_value=%s',
503 '_checkout_email',
504 $email
505 ),
506 );
507 $filter->limit = 10;
508 $filter->page = $page ?? 1;
509 $filter->run_query_count = false;
510 $lp_order_ids = $lp_postdb->get_posts( $filter );
511 if ( ! empty( $lp_order_ids ) ) {
512 $data_to_export = $this->process_order_data( $lp_order_ids );
513 }
514 $done = 10 > count( $lp_order_ids );
515 return array(
516 'data' => $data_to_export,
517 'done' => $done,
518 );
519 }
520
521 /**
522 * Process order data to export
523 *
524 * @param array $lp_order_ids
525 *
526 * @return array
527 * @throws Exception
528 */
529 protected function process_order_data( $lp_order_ids ): array {
530 $data_to_export = array();
531 foreach ( $lp_order_ids as $order ) {
532 $data_to_export[] = array(
533 'group_id' => 'learnpress-orders',
534 'group_label' => __( 'LearnPress Orders', 'learnpress' ),
535 'group_description' => __( 'User&#8217;s LearnPress orders data.', 'learnpress' ),
536 'item_id' => 'order-' . $order->ID,
537 'data' => $this->get_order_personal_data( $order->ID ),
538 );
539 }
540 return $data_to_export;
541 }
542
543 /**
544 * Get order personal data
545 *
546 * @param int $order_id
547 *
548 * @return array
549 * @throws Exception
550 */
551 protected function get_order_personal_data( $order_id ): array {
552 $order = learn_press_get_order( $order_id );
553 $data = array();
554 $props = apply_filters(
555 'learnpress/export-order-personal-data/props',
556 array(
557 'order_number' => __( 'Order Number', 'learnpress' ),
558 'order_date' => __( 'Order Date', 'learnpress' ),
559 'total' => __( 'Order Total', 'learnpress' ),
560 'items' => __( 'Items Purchased', 'learnpress' ),
561 'status' => __( 'Status', 'learnpress' ),
562 'payment_method' => __( 'Payment method', 'learnpress' ),
563 'user_ip_address' => __( 'IP Address', 'learnpress' ),
564 'user_agent' => __( 'Browser User Agent', 'learnpress' ),
565 ),
566 $order
567 );
568 foreach ( $props as $prop => $name ) {
569 $value = '';
570 switch ( $prop ) {
571 case 'items':
572 $item_names = array();
573 $items = $order->get_all_items();
574 if ( ! empty( $items ) ) {
575 foreach ( $items as $item ) {
576 $order_item_id = $item['order_item_id'] ?? 0;
577 $order_item_name = $item['order_item_name'] ?? '';
578 $quantity = learn_press_get_order_item_meta( $order_item_id, '_quantity' );
579 $item_names[] = $order_item_name . ' x ' . $quantity;
580 }
581 }
582 $value = implode( ', ', $item_names );
583 break;
584 case 'status':
585 $value = $order::get_status_label( $order->get_status() );
586 break;
587 case 'total':
588 $value = $order->get_formatted_order_total();
589 break;
590 default:
591 if ( is_callable( array( $order, 'get_' . $prop ) ) ) {
592 $value = $order->{"get_$prop"}();
593 }
594 break;
595 }
596
597 $value = apply_filters( 'learnpress/export-order-personal-data-prop', $value, $prop, $order );
598 if ( $value ) {
599 $data[] = array(
600 'name' => $name,
601 'value' => $value,
602 );
603 }
604 }
605
606 return $data;
607 }
608 }
609