Passed
Push — master ( 16e453...952352 )
by Guillaume
03:11
created

src/Services/Harvest.php (3 issues)

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\NotFoundException;
9
use Required\Harvest\Exception\AuthenticationException;
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 15
    public function __construct($accountId, $apiToken)
22
    {
23 15
        $this->client = new Client();
24
25 15
        $this->client->authenticate($accountId, $apiToken);
26 15
    }
27
28 3
    public function projects()
29
    {
30
        try {
31 3
            return array_column($this->client->projects()->all(['']), 'name', 'id');
32 2
        } catch (AuthenticationException $e) {
33 2
            return [];
34
        }
35
    }
36
37 4
    public function tags()
38
    {
39
        try {
40 4
            $taskAssignments = $this->client->projects()->taskAssignments()->all(
41 4
                (int) getenv('timer_project_id'),
42 4
                ['is_active' => true]
43
            );
44
45
            array_walk($taskAssignments, function ($taskAssignment) use (&$tags) {
0 ignored issues
show
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 2
                $tags[$taskAssignment['task']['id']] = $taskAssignment['task']['name'];
47 2
            });
48
49 2
            return $tags;
50 2
        } catch (AuthenticationException $e) {
51 2
            return [];
52
        }
53
    }
54
55 1
    public function pastTimers()
56
    {
57
        try {
58 1
            $harvestTimers = $this->client->timeEntries()->all([
59 1
                'from' => Carbon::today()->subDays(30),
60 1
                'to' => Carbon::today()
61
            ]);
62
63 1
            return $this->convertToPastTimers($harvestTimers);
64
        } catch (AuthenticationException $e) {
65
            return [];
66
        }
67
    }
68
69 6
    public function startTimer()
70
    {
71
        try {
72 6
            $timer = $this->client->timeEntries()->create([
73 6
                'notes' => getenv('timer_description'),
74 6
                'project_id' => (int) getenv('timer_project_id'),
75 6
                'task_id' => (int) getenv('timer_tag_id'),
76 6
                'spent_date' => date('Y-m-d')
77
            ]);
78
79 6
            if (! isset($timer['id'])) {
80 6
                return false;
81
            }
82
        } catch (ValidationFailedException $e) {
83
            return false;
84
        }
85
86 6
        return $timer['id'];
87
    }
88
89 5
    public function stopCurrentTimer()
90
    {
91 5
        if ($timerId = $this->runningTimer()) {
92 5
            $timer = $this->client->timeEntries()->stop($timerId);
93
94 5
            if (! isset($timer['id'])) {
95
                throw new \Exception("Can't stop current running timer.", 1);
96
            }
97
98 5
            return true;
99
        }
100
101 1
        return false;
102
    }
103
104 13
    public function runningTimer()
105
    {
106
        try {
107 13
            $timer = $this->client->timeEntries()->all(['is_running' => true]);
108
109 13
            return $timer[0]['id'] ?? false;
110
        } catch (\Exception $e) {
111
            return false;
112
        }
113
    }
114
115 1
    public function continueTimer($timerId)
116
    {
117 1
        $timer = $this->client->timeEntries()->restart($timerId);
118
119 1
        return $timer['id'] ?? false;
120
    }
121
122 6
    public function deleteTimer($timerId)
123
    {
124
        try {
125 6
            $this->client->timeEntries()->remove($timerId);
126
        } catch (NotFoundException $e) {
127
            return false;
128
        }
129
130 6
        return true;
131
    }
132
133 1
    protected function convertToPastTimers($harvestTimers)
134
    {
135
        return array_map(function ($harvestTimer) {
136 1
            return $this->buildPastTimerObject($harvestTimer);
137 1
        }, $harvestTimers);
138
    }
139
140 1
    protected function buildPastTimerObject($harvestTimer)
141
    {
142 1
        $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 1
        $pastTimer['description'] = $harvestTimer['notes'];
144 1
        $pastTimer['project_id'] = $harvestTimer['project']['id'];
145 1
        $pastTimer['project_name'] = $harvestTimer['project']['name'];
146 1
        $pastTimer['tag_id'] = $harvestTimer['task']['id'];
147 1
        $pastTimer['tags'] = $harvestTimer['task']['name'];
148 1
        $pastTimer['duration'] = CarbonInterval::seconds(
0 ignored issues
show
Bug Best Practice introduced by
The method Carbon\CarbonInterval::seconds() is not static, but was called statically. ( Ignorable by Annotation )

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

148
        $pastTimer['duration'] = CarbonInterval::/** @scrutinizer ignore-call */ seconds(
Loading history...
149 1
            floor($harvestTimer['hours'] * 3600)
150 1
        )->cascade()->format('%H:%I:%S');
151
152 1
        return (object) $pastTimer;
153
    }
154
}
155