diff options
| author | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2025-01-15 09:08:37 +0000 |
|---|---|---|
| committer | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2025-01-15 09:08:37 +0000 |
| commit | 58ca2df83f308e8acf8cddfbae68c3cf6abdd316 (patch) | |
| tree | d9c5f59556525d1e703352dc1ba536096f3e949d /lib/models/Courseware/Task.php | |
| parent | 8da661dad2dcefddce9fbb2bbb0e6dd1d1127db0 (diff) | |
Integration von Peer-Review in Courseware
Closes #2484
Merge request studip/studip!3196
Diffstat (limited to 'lib/models/Courseware/Task.php')
| -rw-r--r-- | lib/models/Courseware/Task.php | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/lib/models/Courseware/Task.php b/lib/models/Courseware/Task.php index 7842830..5f38ce9 100644 --- a/lib/models/Courseware/Task.php +++ b/lib/models/Courseware/Task.php @@ -2,6 +2,7 @@ namespace Courseware; +use Seminar_User; use User; /** @@ -79,6 +80,14 @@ class Task extends \SimpleORMap 'foreign_key' => 'feedback_id', ]; + $config['has_many']['peer_reviews'] = [ + 'class_name' => PeerReview::class, + 'assoc_foreign_key' => 'task_id', + 'on_delete' => 'delete', + 'on_store' => 'store', + 'order_by' => 'ORDER BY mkdate', + ]; + $config['additional_fields']['solver'] = [ 'get' => 'getSolver', ]; @@ -123,12 +132,11 @@ class Task extends \SimpleORMap return 1 === (int) $this->submitted; } - /** - * @param \User|\Seminar_User $user - */ - public function canUpdate($user): bool + public function canUpdate(User|Seminar_User $user): bool { - $perm = false; + // TODO (mel): Das ist hier eine Code-Verdopplung gegenüber: + // $this->userIsASolver($user) + // Mit Nico besprechen switch ($this->solver_type) { case 'autor': if ($this->solver_id === $user->id) { @@ -157,10 +165,7 @@ class Task extends \SimpleORMap return $this->getStructuralElement()->hasEditingPermission($user); } - /** - * @param \User|\Seminar_User $user - */ - public function userIsASolver($user): bool + public function userIsASolver(User|Seminar_User $user): bool { switch ($this->solver_type) { case 'autor': @@ -175,6 +180,11 @@ class Task extends \SimpleORMap return false; } + public function userIsAPeerReviewer(User|Seminar_User $user): bool + { + return $this->isPeerReviewed() && $this->isPeerReviewedBy($user); + } + /** * @return \User|\Statusgruppen|null the solver */ @@ -255,6 +265,53 @@ class Task extends \SimpleORMap $this->store(); } + public function isPeerReviewed(): bool + { + return PeerReview::countBySql('task_id = ?', [$this->id]) !== 0; + } + + public function isPeerReviewedBy(User|Seminar_User $user): bool + { + $sql = 'task_id = ? AND reviewer_id = ? AND reviewer_type = "autor"'; + if (PeerReview::countBySql($sql, [$this->id, $user->id]) !== 0) { + return true; + } + + $sql = 'SELECT reviewer_id FROM cw_peer_reviews WHERE task_id = ? AND reviewer_type = "group"'; + foreach (\DBManager::get()->fetchFirst($sql, [$this->id]) as $reviewerId) { + if (\Statusgruppen::isMemberOf($reviewerId, $user->id)) { + return true; + } + } + + return false; + } + + public function getPeerReviewProcessessWithReviewsBy(User|Seminar_User $user): array + { + return PeerReviewProcess::findBySql( + 'id IN (?)', + array_unique( + array_merge( + \DBManager::get()->fetchFirst( + 'SELECT DISTINCT process_id FROM cw_peer_reviews WHERE task_id = ? AND reviewer_id = ? AND reviewer_type = "autor"', + [$this->id, $user->id] + ), + array_column( + array_filter( + \DBManager::get()->fetchAll( + 'SELECT process_id, reviewer_id FROM cw_peer_reviews WHERE task_id = ? AND reviewer_type = "group"', + [$this->id] + ), + fn($row) => \Statusgruppen::isMemberOf($row['reviewer_id'], $user->id) + ), + 'process_id' + ) + ) + ) + ); + } + private function getStructuralElementProgress(StructuralElement $structural_element): float { $containers = Container::findBySQL('structural_element_id = ?', [intval($structural_element->id)]); |
