aboutsummaryrefslogtreecommitdiff
path: root/lib/models/Courseware/Task.php
diff options
context:
space:
mode:
authorMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2025-01-15 09:08:37 +0000
committerMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2025-01-15 09:08:37 +0000
commit58ca2df83f308e8acf8cddfbae68c3cf6abdd316 (patch)
treed9c5f59556525d1e703352dc1ba536096f3e949d /lib/models/Courseware/Task.php
parent8da661dad2dcefddce9fbb2bbb0e6dd1d1127db0 (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.php75
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)]);