Passed
Pull Request — master (#30)
by Guillaume
38:15 queued 36:45
created

Harvest::runningTimer()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 3
nop 0
dl 0
loc 8
ccs 3
cts 5
cp 0.6
crap 2.2559
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Godbout\Alfred\Time\Services;
4
5
use Carbon\Carbon;
6
use Carbon\CarbonInterval;
7
use Required\Harvest\Client;
8
use Required\Harvest\Exception\AuthenticationException;
9
use Required\Harvest\Exception\NotFoundException;
10
use Required\Harvest\Exception\ValidationFailedException;
11
12
class Harvest extends TimerService
13
{
14
    public $allowsEmptyProject = false;
15
16
    public $allowsEmptyTag = false;
17
18
    private $client;
19
20
21 105
    public function __construct($accountId, $apiToken)
22
    {
23 105
        $this->client = new Client();
24
25 105
        $this->client->authenticate($accountId, $apiToken);
26 105
    }
27
28 13
    public function projects()
29
    {
30
        try {
31 13
            return array_column($this->client->projects()->all(['']), 'name', 'id');
32 2
        } catch (AuthenticationException $e) {
33 2
            return [];
34
        }
35
    }
36
37 24
    public function tags()
38
    {
39
        try {
40 24
            $taskAssignments = $this->client->projects()->taskAssignments()->all(
41 24
                (int) getenv('timer_project_id'),
42 24
                ['is_active' => true]
43
            );
44
45
            array_walk($taskAssignments, function ($taskAssignment) use (&$tags) {
0 ignored issues
show
Bug introduced by
It seems like $taskAssignments can also be of type string; however, parameter $array of array_walk() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
            array_walk(/** @scrutinizer ignore-type */ $taskAssignments, function ($taskAssignment) use (&$tags) {
Loading history...
46 22
                $tags[$taskAssignment['task']['id']] = $taskAssignment['task']['name'];
47 22
            });
48
49 22
            return $tags;
50 2
        } catch (AuthenticationException $e) {
51 2
            return [];
52
        }
53
    }
54
55 11
    public function pastTimers()
56
    {
57
        try {
58 11
            $harvestTimers = $this->client->timeEntries()->all([
59 11
                'from' => Carbon::today()->subDays(30),
60 11
                'to' => Carbon::today()
61
            ]);
62
63 11
            return $this->convertToPastTimers($harvestTimers);
64
        } catch (AuthenticationException $e) {
65
            return [];
66
        }
67
    }
68
69 66
    public function startTimer()
70
    {
71
        try {
72 66
            $timer = $this->client->timeEntries()->create([
73 66
                'notes' => getenv('timer_description'),
74 66
                'project_id' => (int) getenv('timer_project_id'),
75 66
                'task_id' => (int) getenv('timer_tag_id'),
76 66
                'spent_date' => date('Y-m-d')
77
            ]);
78
79 66
            if (! isset($timer['id'])) {
80 66
                return false;
81
            }
82
        } catch (ValidationFailedException $e) {
83
            return false;
84
        }
85
86 66
        return $timer['id'];
87
    }
88
89 54
    public function stopCurrentTimer()
90
    {
91 54
        if ($timerId = $this->runningTimer()) {
92 53
            $timer = $this->client->timeEntries()->stop($timerId);
93
94 53
            if (! isset($timer['id'])) {
95
                throw new \Exception("Can't stop current running timer.", 1);
96
            }
97
98 53
            return true;
99
        }
100
101 12
        return false;
102
    }
103
104 103
    public function runningTimer()
105
    {
106
        try {
107 103
            $timer = $this->client->timeEntries()->all(['is_running' => true]);
108
109 103
            return $timer[0]['id'] ?? false;
110
        } catch (\Exception $e) {
111
            return false;
112
        }
113
    }
114
115 11
    public function continueTimer($timerId)
116
    {
117 11
        $timer = $this->client->timeEntries()->restart($timerId);
118
119 11
        return $timer['id'] ?? false;
120
    }
121
122 65
    public function deleteTimer($timerId)
123
    {
124
        try {
125 65
            $this->client->timeEntries()->remove($timerId);
126 1
        } catch (NotFoundException $e) {
127 1
            return false;
128
        }
129
130 64
        return true;
131
    }
132
133 11
    protected function convertToPastTimers($harvestTimers)
134
    {
135
        return array_map(function ($harvestTimer) {
136 11
            return $this->buildPastTimerObject($harvestTimer);
137 11
        }, $harvestTimers);
138
    }
139
140 11
    protected function buildPastTimerObject($harvestTimer)
141
    {
142 11
        $pastTimer['id'] = $harvestTimer['id'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$pastTimer was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pastTimer = array(); before regardless.
Loading history...
143 11
        $pastTimer['description'] = $harvestTimer['notes'];
144 11
        $pastTimer['project_id'] = $harvestTimer['project']['id'];
145 11
        $pastTimer['project_name'] = $harvestTimer['project']['name'];
146 11
        $pastTimer['tag_id'] = $harvestTimer['task']['id'];
147 11
        $pastTimer['tags'] = $harvestTimer['task']['name'];
148 11
        $pastTimer['duration'] = CarbonInterval::seconds(
149 11
            floor($harvestTimer['hours'] * 3600)
150 11
        )->cascade()->format('%H:%I:%S');
151
152 11
        return (object) $pastTimer;
153
    }
154
}
155