Forked from
Stud.IP / Stud.IP
3656 commits behind the upstream repository.
-
Jan-Hendrik Willms authored
Closes #979 Merge request studip/studip!564
Jan-Hendrik Willms authoredCloses #979 Merge request studip/studip!564
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Task.php 5.98 KiB
<?php
namespace Courseware;
use User;
/**
* Courseware's tasks.
*
* @author Ron Lucke <lucke@elan-ev.de>
* @license GPL2 or any later version
*
* @since Stud.IP 5.1
*
* @property int $id database column
* @property int $task_group_id database column
* @property int $structural_element_id database column
* @property string $solver_id database column
* @property string $solver_type database column
* @property int $submission_date database column
* @property int $submitted database column
* @property string $renewal database column
* @property int $renewal_date database column
* @property int $feedback_id database column
* @property int $mkdate database column
* @property int $chdate database column
* @property \Courseware\TaskGroup $task_group belongs_to Courseware\TaskGroup
* @property \Courseware\StructuralElement $structural_element belongs_to Courseware\TaskGroup
* @property \User $user belongs_to User
* @property \Statusgruppen $group belongs_to Statusgruppen
* @property \Courseware\TaskFeedback $task_feedback belongs_to Courseware\TaskFeedback
* @property-read \User|\Statusgruppen|null $solver belongs_to User or Statusgruppen
*/
class Task extends \SimpleORMap
{
protected static function configure($config = [])
{
$config['db_table'] = 'cw_tasks';
$config['belongs_to']['task_group'] = [
'class_name' => TaskGroup::class,
'foreign_key' => 'task_group_id',
];
$config['belongs_to']['structural_element'] = [
'class_name' => StructuralElement::class,
'foreign_key' => 'structural_element_id',
];
$config['belongs_to']['lecturer'] = [
'class_name' => User::class,
'foreign_key' => 'lecturer_id',
];
$config['belongs_to']['user'] = [
'class_name' => User::class,
'foreign_key' => 'solver_id',
'assoc_foreign_key' => 'user_id',
];
$config['belongs_to']['group'] = [
'class_name' => \Statusgruppen::class,
'foreign_key' => 'solver_id',
'assoc_foreign_key' => 'statusgruppe_id',
];
$config['belongs_to']['course'] = [
'class_name' => \Course::class,
'foreign_key' => 'seminar_id',
];
$config['belongs_to']['task_feedback'] = [
'class_name' => TaskFeedback::class,
'foreign_key' => 'feedback_id',
];
$config['additional_fields']['solver'] = [
'get' => 'getSolver',
'set' => false,
];
parent::configure($config);
}
/**
* Returns the structural element of this task.
* This structural element and all its children are part of the task.
*
* @return StructuralElement the structural element
*/
public function getStructuralElement(): StructuralElement
{
return $this->structural_element;
}
/**
* Returns the feedback for this task.
*
* @return TaskFeedback the task feedback
*/
public function getFeedback(): ?TaskFeedback
{
return $this->task_feedback;
}
/**
* @return bool true if task is submitted
*/
public function isSubmitted(): bool
{
return 1 === (int) $this->submitted;
}
/**
* @param \User|\Seminar_User $user
*/
public function canUpdate($user): bool
{
$perm = false;
switch ($this->solver_type) {
case 'autor':
if ($this->solver_id === $user->id) {
return true;
}
break;
case 'group':
$group = \Statusgruppen::find($this->solver_id);
if (isset($group) && $group->isMember($user->id)) {
return true;
}
break;
}
return $this->getStructuralElement()->hasEditingPermission($user);
}
/**
* @param \User|\Seminar_User $user
*/
public function userIsASolver($user): bool
{
switch ($this->solver_type) {
case 'autor':
return $this->solver_id === $user->id;
case 'group':
$group = $this->getSolver();
return $group->isMember($user->id);
}
return false;
}
/**
* @return \User|\Statusgruppen|null the solver
*/
public function getSolver()
{
switch ($this->solver_type) {
case 'autor':
return \User::find($this->solver_id);
case 'group':
return \Statusgruppen::find($this->solver_id);
}
return null;
}
public function getTaskProgress(): float
{
$children = $this->structural_element->findDescendants();
$element_counter = 1;
$progress = $this->getStructuralElementProgress($this->structural_element);
foreach ($children as $child) {
++$element_counter;
$progress = ($this->getStructuralElementProgress($child) + $progress) / $element_counter;
}
return $progress * 100;
}
private function getStructuralElementProgress(StructuralElement $structural_element): float
{
$containers = Container::findBySQL('structural_element_id = ?', [intval($structural_element->id)]);
$counter = 0;
$progress = 0;
$b = [];
foreach ($containers as $container) {
$blockCount = $container->countBlocks();
$counter += $blockCount;
if ($blockCount > 0) {
$blocks = Block::findBySQL('container_id = ?', [$container->id]);
foreach ($blocks as $block) {
$b[] = $block->id;
if ($this->task_group->lecturer_id === $block->owner_id && $block->owner_id !== $block->editor_id) {
++$progress;
}
}
}
}
if ($counter > 0) {
return $progress / $counter;
}
return 0;
}
}