Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
26.92% |
7 / 26 |
CRAP | |
61.11% |
55 / 90 |
| TaskState | |
0.00% |
0 / 1 |
|
40.62% |
13 / 32 |
271.73 | |
61.11% |
55 / 90 |
| getState | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| getStatusItems | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
| getStatusLabel | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 9 |
|||
| proceed | |
0.00% |
0 / 1 |
5.05 | |
87.50% |
7 / 8 |
|||
| reset | |
0.00% |
0 / 1 |
2.06 | |
75.00% |
3 / 4 |
|||
| canProceed | |
0.00% |
0 / 1 |
4.07 | |
83.33% |
5 / 6 |
|||
| getProceedStatuses | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getProceedConfig | |
100.00% |
1 / 1 |
3 | |
100.00% |
6 / 6 |
|||
| getDefaultProceedStatusId | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| getDefaultProceedState | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| revert | |
0.00% |
0 / 1 |
5.39 | |
75.00% |
6 / 8 |
|||
| canRevert | |
0.00% |
0 / 1 |
4.07 | |
83.33% |
5 / 6 |
|||
| getRevertStatuses | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getRevertConfig | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| getDefaultRevertStatusId | |
0.00% |
0 / 1 |
2.15 | |
66.67% |
2 / 3 |
|||
| getDefaultRevertState | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| changeStatus | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| getStateInstance | |
0.00% |
0 / 1 |
2.03 | |
80.00% |
4 / 5 |
|||
| getCheckUrl | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 5 |
|||
| getProceedUrl | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| getRevertUrl | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| isPending | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| isInProgress | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| isPendingReview | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| isCompleted | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| getStatusId | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| proceedConfig | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| revertConfig | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| checkRevertRules | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| checkProceedRules | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| afterProceed | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| afterRevert | |
100.00% |
1 / 1 |
1 | n/a |
0 / 0 |
||||
| <?php | |
| namespace humhub\modules\tasks\models\state; | |
| use humhub\modules\tasks\helpers\TaskUrl; | |
| use humhub\modules\tasks\models\Task; | |
| use Yii; | |
| use yii\base\Component; | |
| /** | |
| * Class TaskState | |
| * @todo change base class back to BaseObject after v1.3 stable | |
| * @package humhub\modules\tasks\models\state | |
| */ | |
| abstract class TaskState extends Component | |
| { | |
| const STATES = [ | |
| Task::STATUS_PENDING => PendingState::class, | |
| Task::STATUS_IN_PROGRESS => InProgressState::class, | |
| Task::STATUS_PENDING_REVIEW => PendingReviewState::class, | |
| Task::STATUS_COMPLETED => CompletedState::class | |
| ]; | |
| public static $status; | |
| public static $defaultProceedStatus; | |
| public static $defaultRevertStatus; | |
| /** | |
| * @var Task | |
| */ | |
| public $task; | |
| public static function getState($task) | |
| { | |
| $states = static::STATES; | |
| $stateClass = isset($states[$task->status]) ? $states[$task->status] : $states[Task::STATUS_PENDING]; | |
| return Yii::createObject([ | |
| 'class' => $stateClass, | |
| 'task' => $task | |
| ]); | |
| } | |
| /** | |
| * Returns an array of statusItems. | |
| * Primary used in TaskFilter | |
| * | |
| * @return array | |
| */ | |
| public static function getStatusItems() | |
| { | |
| return [ | |
| Task::STATUS_PENDING => Yii::t('TasksModule.views_index_index', 'Pending'), | |
| Task::STATUS_IN_PROGRESS => Yii::t('TasksModule.views_index_index', 'In Progress'), | |
| Task::STATUS_PENDING_REVIEW => Yii::t('TasksModule.views_index_index', 'In Review'), | |
| Task::STATUS_COMPLETED => Yii::t('TasksModule.views_index_index', 'Completed'), | |
| ]; | |
| } | |
| /** | |
| * send label for change-status button | |
| * @return string $statusLabel | |
| */ | |
| public function getStatusLabel() | |
| { | |
| switch ($this->status) { | |
| case Task::STATUS_PENDING: | |
| $statusLabel = Yii::t('TasksModule.base', 'Begin Task'); | |
| break; | |
| case Task::STATUS_IN_PROGRESS: | |
| return $this->review ? Yii::t('TasksModule.base', 'Let Task Review') | |
| : Yii::t('TasksModule.base', 'Finish Task'); | |
| break; | |
| case Task::STATUS_PENDING_REVIEW: | |
| $statusLabel = Yii::t('TasksModule.base', 'Finish Task'); | |
| break; | |
| default : | |
| $statusLabel = ''; | |
| } | |
| return $statusLabel; | |
| } | |
| public function proceed($newStatus = null) | |
| { | |
| if($newStatus instanceof TaskState) { | |
| $newStatus = $newStatus->getStatusId(); | |
| } else { | |
| $newStatus = ($newStatus) ? $newStatus : $this->getDefaultProceedStatusId(); | |
| } | |
| if(!array_key_exists($newStatus, static::STATES) || !$this->canProceed($newStatus)) { | |
| return false; | |
| } | |
| $this->changeStatus($newStatus); | |
| $this->task->state->afterProceed($this); | |
| return true; | |
| } | |
| public function reset() | |
| { | |
| if($this->canRevert(Task::STATUS_PENDING)) { | |
| $this->revert(Task::STATUS_PENDING); | |
| return true; | |
| } | |
| return false; | |
| } | |
| public function canProceed($newStatus = null, $user = null) { | |
| if($newStatus instanceof TaskState) { | |
| $newStatus = $newStatus->getStatusId(); | |
| } else { | |
| $newStatus = ($newStatus) ? $newStatus : $this->getDefaultProceedStatusId(); | |
| } | |
| if(!in_array($newStatus, $this->getProceedStatuses($user))) { | |
| return false; | |
| } | |
| return $this->checkProceedRules($newStatus, $user); | |
| } | |
| public function getProceedStatuses($user = null) | |
| { | |
| return array_keys($this->getProceedConfig($user)); | |
| } | |
| public function getProceedConfig($user = null) | |
| { | |
| $result = $this->proceedConfig($user); | |
| if(!$this->task->review) { | |
| unset($result[Task::STATUS_PENDING_REVIEW]); | |
| } | |
| if(!$this->getStateInstance(Task::STATUS_COMPLETED)->canCompleteTask($user)) { | |
| unset($result[Task::STATUS_COMPLETED]); | |
| } | |
| return $result; | |
| } | |
| protected function getDefaultProceedStatusId() | |
| { | |
| if(static::$defaultProceedStatus) { | |
| return static::$defaultProceedStatus; | |
| } | |
| return null; | |
| } | |
| /** | |
| * @return TaskState | |
| */ | |
| public function getDefaultProceedState() | |
| { | |
| return $this->getStateInstance($this->getDefaultProceedStatusId()); | |
| } | |
| public function revert($newStatus = null) | |
| { | |
| if($newStatus instanceof TaskState) { | |
| $newStatus = $newStatus->getStatusId(); | |
| } else { | |
| $newStatus = ($newStatus) ? $newStatus : $this->getDefaultRevertStatusId(); | |
| } | |
| if(!array_key_exists($newStatus, static::STATES) || !$this->canRevert($newStatus)) { | |
| return false; | |
| } | |
| $this->changeStatus($newStatus); | |
| $this->task->state->afterRevert($this); | |
| return true; | |
| } | |
| public function canRevert($newStatus = null, $user = null) | |
| { | |
| if($newStatus instanceof TaskState) { | |
| $newStatus = $newStatus->getStatusId(); | |
| } else { | |
| $newStatus = ($newStatus) ? $newStatus : $this->getDefaultRevertStatusId(); | |
| } | |
| if(!in_array($newStatus, $this->getRevertStatuses($user))) { | |
| return false; | |
| } | |
| return $this->checkRevertRules($newStatus, $user); | |
| } | |
| public function getRevertStatuses($user = null) | |
| { | |
| return array_keys($this->getRevertConfig($user)); | |
| } | |
| public function getRevertConfig($user = null) | |
| { | |
| $result = $this->revertConfig($user); | |
| if(!$this->task->review) { | |
| unset($result[Task::STATUS_PENDING_REVIEW]); | |
| } | |
| return $result; | |
| } | |
| protected function getDefaultRevertStatusId() | |
| { | |
| if(static::$defaultRevertStatus) { | |
| return static::$defaultRevertStatus; | |
| } | |
| return null; | |
| } | |
| public function getDefaultRevertState() | |
| { | |
| return $this->getStateInstance($this->getDefaultRevertStatusId()); | |
| } | |
| protected function changeStatus($status) | |
| { | |
| $this->task->status = $status; | |
| $this->task->save(); | |
| } | |
| /** | |
| * @param $newState | |
| * @return TaskState | |
| */ | |
| public function getStateInstance($newState) | |
| { | |
| if($newState) { | |
| return Yii::createObject([ | |
| 'class' => static::STATES[$newState], | |
| 'task' => $this->task | |
| ]); | |
| } | |
| return null; | |
| } | |
| public function getCheckUrl() | |
| { | |
| if($this->canProceed(Task::STATUS_COMPLETED)) { | |
| return $this->getStateInstance(Task::STATUS_COMPLETED)->getProceedUrl(); | |
| } else if ($this->canProceed(Task::STATUS_PENDING_REVIEW)) { | |
| return $this->getStateInstance(Task::STATUS_PENDING_REVIEW)->getProceedUrl(); | |
| } | |
| return null; | |
| } | |
| public function getProceedUrl() | |
| { | |
| return TaskUrl::proceedTask($this->task, static::$status); | |
| } | |
| public function getRevertUrl() | |
| { | |
| return TaskUrl::revertTask($this->task, static::$status); | |
| } | |
| public function isPending() | |
| { | |
| return ($this->task->status === Task::STATUS_PENDING); | |
| } | |
| public function isInProgress() | |
| { | |
| return ($this->task->status === Task::STATUS_IN_PROGRESS); | |
| } | |
| public function isPendingReview() | |
| { | |
| return ($this->task->status === Task::STATUS_PENDING_REVIEW); | |
| } | |
| public function isCompleted() | |
| { | |
| return ($this->task->status === Task::STATUS_COMPLETED); | |
| } | |
| public function getStatusId() | |
| { | |
| return static::$status; | |
| } | |
| protected abstract function proceedConfig($user = null); | |
| protected abstract function revertConfig($user = null); | |
| public abstract function checkRevertRules($newStatus = null, $user = null); | |
| public abstract function checkProceedRules($newStatus = null, $user = null); | |
| public abstract function afterProceed(TaskState $oldState); | |
| public abstract function afterRevert(TaskState $oldState); | |
| } |