|
53 | 53 | use core_competency\user_evidence_competency; |
54 | 54 | use core_competency\external\performance_helper; |
55 | 55 | use core_privacy\local\metadata\collection; |
| 56 | +use core_privacy\local\request\approved_userlist; |
56 | 57 | use core_privacy\local\request\contextlist; |
57 | 58 | use core_privacy\local\request\approved_contextlist; |
58 | 59 | use core_privacy\local\request\transform; |
| 60 | +use core_privacy\local\request\userlist; |
59 | 61 | use core_privacy\local\request\writer; |
60 | 62 |
|
61 | 63 | /** |
|
68 | 70 | */ |
69 | 71 | class provider implements |
70 | 72 | \core_privacy\local\metadata\provider, |
| 73 | + \core_privacy\local\request\core_userlist_provider, |
71 | 74 | \core_privacy\local\request\subsystem\provider { |
72 | 75 |
|
73 | 76 | /** |
@@ -418,6 +421,166 @@ public static function get_contexts_for_userid(int $userid) : contextlist { |
418 | 421 | return $contextlist; |
419 | 422 | } |
420 | 423 |
|
| 424 | + /** |
| 425 | + * Get the list of users who have data within a context. |
| 426 | + * |
| 427 | + * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. |
| 428 | + */ |
| 429 | + public static function get_users_in_context(userlist $userlist) { |
| 430 | + $context = $userlist->get_context(); |
| 431 | + $params = ['contextid' => $context->id]; |
| 432 | + |
| 433 | + // Add users who have modified the frameworks and related data in the context. |
| 434 | + $sql = " |
| 435 | + SELECT cf.usermodified |
| 436 | + FROM {" . competency_framework::TABLE . "} cf |
| 437 | + WHERE cf.contextid = :contextid"; |
| 438 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 439 | + |
| 440 | + $sql = " |
| 441 | + SELECT c.usermodified |
| 442 | + FROM {" . competency_framework::TABLE . "} cf |
| 443 | + JOIN {" . competency::TABLE . "} c |
| 444 | + ON c.competencyframeworkid = cf.id |
| 445 | + WHERE cf.contextid = :contextid"; |
| 446 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 447 | + |
| 448 | + $sql = " |
| 449 | + SELECT cr.usermodified |
| 450 | + FROM {" . competency_framework::TABLE . "} cf |
| 451 | + JOIN {" . competency::TABLE . "} c |
| 452 | + ON c.competencyframeworkid = cf.id |
| 453 | + JOIN {" . related_competency::TABLE . "} cr |
| 454 | + ON cr.competencyid = c.id |
| 455 | + WHERE cf.contextid = :contextid"; |
| 456 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 457 | + |
| 458 | + // Add users who have modified the templates and related data in the context. |
| 459 | + $sql = " |
| 460 | + SELECT tpl.usermodified |
| 461 | + FROM {" . template::TABLE . "} tpl |
| 462 | + WHERE tpl.contextid = :contextid"; |
| 463 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 464 | + |
| 465 | + $sql = " |
| 466 | + SELECT tch.usermodified |
| 467 | + FROM {" . template::TABLE . "} tpl |
| 468 | + JOIN {" . template_cohort::TABLE . "} tch |
| 469 | + ON tch.templateid = tpl.id |
| 470 | + WHERE tpl.contextid = :contextid"; |
| 471 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 472 | + |
| 473 | + $sql = " |
| 474 | + SELECT tc.usermodified |
| 475 | + FROM {" . template::TABLE . "} tpl |
| 476 | + JOIN {" . template_competency::TABLE . "} tc |
| 477 | + ON tc.templateid = tpl.id |
| 478 | + WHERE tpl.contextid = :contextid"; |
| 479 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 480 | + |
| 481 | + // Add users if userlist is in course context. |
| 482 | + if (is_a($context, \context_course::class)) { |
| 483 | + $params = ['courseid' => $context->instanceid]; |
| 484 | + |
| 485 | + $sql = " |
| 486 | + SELECT cc.usermodified |
| 487 | + FROM {" . course_competency::TABLE . "} cc |
| 488 | + WHERE cc.courseid = :courseid"; |
| 489 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 490 | + |
| 491 | + $sql = " |
| 492 | + SELECT ccs.usermodified |
| 493 | + FROM {" . course_competency_settings::TABLE . "} ccs |
| 494 | + WHERE ccs.courseid = :courseid"; |
| 495 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 496 | + |
| 497 | + $sql = " |
| 498 | + SELECT ucc.userid, ucc.usermodified |
| 499 | + FROM {" . user_competency_course::TABLE . "} ucc |
| 500 | + WHERE ucc.courseid = :courseid"; |
| 501 | + $userlist->add_from_sql('userid', $sql, $params); |
| 502 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 503 | + |
| 504 | + } else if (is_a($context, \context_module::class)) { |
| 505 | + // Add users if userlist is in module context. |
| 506 | + $params = ['moduleid' => $context->instanceid]; |
| 507 | + |
| 508 | + $sql = " |
| 509 | + SELECT cmc.usermodified |
| 510 | + FROM {" . course_module_competency::TABLE . "} cmc |
| 511 | + WHERE cmc.cmid = :moduleid"; |
| 512 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 513 | + |
| 514 | + } else if (is_a($context, \context_user::class)) { |
| 515 | + $params = ['userid' => $context->instanceid]; |
| 516 | + |
| 517 | + // Add users through plan related data. |
| 518 | + $sql = " |
| 519 | + SELECT p.userid, p.usermodified, p.reviewerid |
| 520 | + FROM {" . plan::TABLE . "} p |
| 521 | + WHERE p.userid = :userid"; |
| 522 | + $userlist->add_from_sql('userid', $sql, $params); |
| 523 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 524 | + $userlist->add_from_sql('reviewerid', $sql, $params); |
| 525 | + |
| 526 | + $sql = " |
| 527 | + SELECT pc.usermodified |
| 528 | + FROM {" . plan::TABLE . "} p |
| 529 | + JOIN {" . plan_competency::TABLE . "} pc |
| 530 | + ON pc.planid = p.id |
| 531 | + WHERE p.userid = :userid"; |
| 532 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 533 | + |
| 534 | + $sql = " |
| 535 | + SELECT upc.usermodified |
| 536 | + FROM {" . user_competency_plan::TABLE . "} upc |
| 537 | + WHERE upc.userid = :userid"; |
| 538 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 539 | + |
| 540 | + // Add users through competency data. |
| 541 | + $sql = " |
| 542 | + SELECT uc.userid, uc.usermodified, uc.reviewerid |
| 543 | + FROM {" . user_competency::TABLE . "} uc |
| 544 | + WHERE uc.userid = :userid"; |
| 545 | + $userlist->add_from_sql('userid', $sql, $params); |
| 546 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 547 | + $userlist->add_from_sql('reviewerid', $sql, $params); |
| 548 | + |
| 549 | + $sql = " |
| 550 | + SELECT e.usermodified, e.actionuserid |
| 551 | + FROM {" . user_competency::TABLE . "} uc |
| 552 | + JOIN {" . evidence::TABLE . "} e |
| 553 | + ON e.usercompetencyid = uc.id |
| 554 | + WHERE uc.userid = :userid"; |
| 555 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 556 | + $userlist->add_from_sql('actionuserid', $sql, $params); |
| 557 | + |
| 558 | + // Add users through evidence data. |
| 559 | + $sql = " |
| 560 | + SELECT ue.userid, ue.usermodified |
| 561 | + FROM {" . user_evidence::TABLE . "} ue |
| 562 | + WHERE ue.userid = :userid"; |
| 563 | + $userlist->add_from_sql('userid', $sql, $params); |
| 564 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 565 | + |
| 566 | + $sql = " |
| 567 | + SELECT ue.usermodified |
| 568 | + FROM {" . user_evidence::TABLE . "} ue |
| 569 | + JOIN {" . user_evidence_competency::TABLE . "} uec |
| 570 | + ON uec.userevidenceid = ue.id |
| 571 | + WHERE ue.userid = :userid"; |
| 572 | + $userlist->add_from_sql('usermodified', $sql, $params); |
| 573 | + } |
| 574 | + |
| 575 | + // Add users who commented in the context. |
| 576 | + // Note: Comment component must be competency and not core_competency. |
| 577 | + \core_comment\privacy\provider::get_users_in_context_from_sql( |
| 578 | + $userlist, 'com', 'competency', 'plan', $context->id); |
| 579 | + |
| 580 | + \core_comment\privacy\provider::get_users_in_context_from_sql( |
| 581 | + $userlist, 'com', 'competency', 'user_competency', $context->id); |
| 582 | + } |
| 583 | + |
421 | 584 | /** |
422 | 585 | * Export all user data for the specified user, in the specified contexts. |
423 | 586 | * |
@@ -478,8 +641,7 @@ public static function delete_data_for_all_users_in_context(context $context) { |
478 | 641 | break; |
479 | 642 |
|
480 | 643 | case CONTEXT_COURSE: |
481 | | - $courseid = $context->instanceid; |
482 | | - $DB->delete_records(user_competency_course::TABLE, ['courseid' => $courseid]); |
| 644 | + static::delete_user_competencies_in_course($context->instanceid); |
483 | 645 | break; |
484 | 646 | } |
485 | 647 | } |
@@ -511,12 +673,43 @@ public static function delete_data_for_user(approved_contextlist $contextlist) { |
511 | 673 | break; |
512 | 674 |
|
513 | 675 | case CONTEXT_COURSE: |
514 | | - static::delete_user_competencies_in_course($userid, $context->instanceid); |
| 676 | + static::delete_user_competencies_in_course($context->instanceid, [$userid]); |
515 | 677 | break; |
516 | 678 | } |
517 | 679 | } |
518 | 680 | } |
519 | 681 |
|
| 682 | + /** |
| 683 | + * Delete multiple users within a single context. |
| 684 | + * |
| 685 | + * Here we only delete the private data of users, not whether they modified, are reviewing, |
| 686 | + * or are associated with the record on at a second level. Only data directly linked to the |
| 687 | + * user will be affected. |
| 688 | + * |
| 689 | + * @param approved_userlist $userlist The approved context and user information to delete information for. |
| 690 | + */ |
| 691 | + public static function delete_data_for_users(approved_userlist $userlist) { |
| 692 | + $context = $userlist->get_context(); |
| 693 | + $userids = $userlist->get_userids(); |
| 694 | + |
| 695 | + switch ($context->contextlevel) { |
| 696 | + case CONTEXT_USER: |
| 697 | + // Only delete the user's information when their context is being deleted. |
| 698 | + // We do not take any action on other user's contexts because we don't own the data there. |
| 699 | + if (in_array($context->instanceid, $userids)) { |
| 700 | + static::delete_user_evidence_of_prior_learning($context->instanceid); |
| 701 | + static::delete_user_plans($context->instanceid); |
| 702 | + static::delete_user_competencies($context->instanceid); |
| 703 | + } |
| 704 | + |
| 705 | + break; |
| 706 | + |
| 707 | + case CONTEXT_COURSE: |
| 708 | + static::delete_user_competencies_in_course($context->instanceid, $userids); |
| 709 | + break; |
| 710 | + } |
| 711 | + } |
| 712 | + |
520 | 713 | /** |
521 | 714 | * Delete evidence of prior learning. |
522 | 715 | * |
@@ -602,15 +795,26 @@ protected static function delete_user_competencies($userid) { |
602 | 795 | } |
603 | 796 |
|
604 | 797 | /** |
605 | | - * Delete the record of competencies for a user in a course. |
| 798 | + * Delete the record of competencies for user(s) in a course. |
606 | 799 | * |
607 | | - * @param int $userid The user ID. |
608 | 800 | * @param int $courseid The course ID. |
| 801 | + * @param int[] $userids The user IDs, if deleting for specific user(s). |
609 | 802 | * @return void |
610 | 803 | */ |
611 | | - protected static function delete_user_competencies_in_course($userid, $courseid) { |
| 804 | + protected static function delete_user_competencies_in_course($courseid, $userids = []) { |
612 | 805 | global $DB; |
613 | | - $DB->delete_records(user_competency_course::TABLE, ['userid' => $userid, 'courseid' => $courseid]); |
| 806 | + |
| 807 | + $params = ['courseid' => $courseid]; |
| 808 | + $where = "courseid = :courseid"; |
| 809 | + |
| 810 | + if (!empty($userids)) { |
| 811 | + list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); |
| 812 | + $params = $params + $inparams; |
| 813 | + |
| 814 | + $where .= " AND userid {$insql}"; |
| 815 | + } |
| 816 | + |
| 817 | + $DB->delete_records_select(user_competency_course::TABLE, $where, $params); |
614 | 818 | } |
615 | 819 |
|
616 | 820 | /** |
|
0 commit comments