Passed
Push — master ( 853bda...782fe1 )
by Guillaume
06:08
created

Harvest::deleteTimer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
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 48
    public function __construct($accountId, $apiToken)
22
    {
23 48
        $this->client = new Client();
24
25 48
        $this->client->authenticate($accountId, $apiToken);
26 48
    }
27
28 16
    public function projects()
29
    {
30
        try {
31 16
            return array_column($this->client->projects()->all(['']), 'name', 'id');
32 16
        } catch (AuthenticationException $e) {
33 16
            return [];
34
        }
35
    }
36
37 16
    public function tags()
38
    {
39
        try {
40 16
            $taskAssignments = $this->client->projects()->taskAssignments()->all(
41 16
                (int) getenv('timer_project_id'),
42 16
                ['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
                $tags[$taskAssignment['task']['id']] = $taskAssignment['task']['name'];
47
            });
48
49
            return $tags;
50 16
        } catch (AuthenticationException $e) {
51 16
            return [];
52
        }
53
    }
54
55
    public function pastTimers()
56
    {
57
        try {
58
            $harvestTimers = $this->client->timeEntries()->all([
59
                'from' => Carbon::today()->subDays(30),
60
                'to' => Carbon::today()
61
            ]);
62
63
            return $this->convertToPastTimers($harvestTimers);
64
        } catch (AuthenticationException $e) {
65
            return [];
66
        }
67
    }
68
69
    public function startTimer()
70
    {
71
        try {
72
            $timer = $this->client->timeEntries()->create([
73
                'notes' => getenv('timer_description'),
74
                'project_id' => (int) getenv('timer_project_id'),
75
                'task_id' => (int) getenv('timer_tag_id'),
76
                'spent_date' => date('Y-m-d')
77
            ]);
78
79
            if (! isset($timer['id'])) {
80
                return false;
81
            }
82
        } catch (ValidationFailedException $e) {
83
            return false;
84
        }
85
86
        return $timer['id'];
87
    }
88
89 2
    public function stopCurrentTimer()
90
    {
91 2
        if ($timerId = $this->runningTimer()) {
92 1
            $timer = $this->client->timeEntries()->stop($timerId);
93
94 1
            if (! isset($timer['id'])) {
95
                throw new \Exception("Can't stop current running timer.", 1);
96
            }
97
98 1
            return true;
99
        }
100
101 1
        return false;
102
    }
103
104 32
    public function runningTimer()
105
    {
106
        try {
107 32
            $timer = $this->client->timeEntries()->all(['is_running' => true]);
108
109 32
            return $timer[0]['id'] ?? false;
110
        } catch (\Exception $e) {
111
            return false;
112
        }
113
    }
114
115
    public function continueTimer($timerId)
116
    {
117
        $timer = $this->client->timeEntries()->restart($timerId);
118
119
        return $timer['id'] ?? false;
120
    }
121
122 2
    public function deleteTimer($timerId)
123
    {
124
        try {
125 2
            $this->client->timeEntries()->remove($timerId);
126 1
        } catch (NotFoundException $e) {
127 1
            return false;
128
        }
129
130 1
        return true;
131
    }
132
133
    protected function convertToPastTimers($harvestTimers)
134
    {
135
        return array_map(function ($harvestTimer) {
136
            return $this->buildPastTimerObject($harvestTimer);
137
        }, $harvestTimers);
138
    }
139
140
    protected function buildPastTimerObject($harvestTimer)
141
    {
142
        $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
        $pastTimer['description'] = $harvestTimer['notes'];
144
        $pastTimer['project_id'] = $harvestTimer['project']['id'];
145
        $pastTimer['project_name'] = $harvestTimer['project']['name'];
146
        $pastTimer['tag_id'] = $harvestTimer['task']['id'];
147
        $pastTimer['tags'] = $harvestTimer['task']['name'];
148
        $pastTimer['duration'] = CarbonInterval::seconds(
149
            floor($harvestTimer['hours'] * 3600)
150
        )->cascade()->format('%H:%I:%S');
151
152
        return (object) $pastTimer;
153
    }
154
}
155