Completed
Push — master ( 3b0b6a...263c36 )
by Guillaume
02:53
created

src/Services/Harvest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
    public function __construct($accountId, $apiToken)
22
    {
23
        $this->client = new Client();
24
25
        $this->client->authenticate($accountId, $apiToken);
26
    }
27
28
    public function projects()
29
    {
30
        try {
31
            return array_column($this->client->projects()->all(['']), 'name', 'id');
32
        } catch (AuthenticationException $e) {
33
            return [];
34
        }
35
    }
36
37
    public function tags()
38
    {
39
        try {
40
            $taskAssignments = $this->client->projects()->taskAssignments()->all(
41
                (int) getenv('timer_project_id'),
42
                ['is_active' => true]
43
            );
44
45
            array_walk($taskAssignments, function ($taskAssignment) use (&$tags) {
46
                $tags[$taskAssignment['task']['id']] = $taskAssignment['task']['name'];
47
            });
48
49
            return $tags;
50
        } catch (AuthenticationException $e) {
51
            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 View Code Duplication
    public function stopCurrentTimer()
90
    {
91
        if ($timerId = $this->runningTimer()) {
92
            $timer = $this->client->timeEntries()->stop($timerId);
93
94
            if (! isset($timer['id'])) {
95
                throw new \Exception("Can't stop current running timer.", 1);
96
97
                return false;
98
            }
99
100
            return true;
101
        }
102
103
        return false;
104
    }
105
106
    public function runningTimer()
107
    {
108
        try {
109
            $timer = $this->client->timeEntries()->all(['is_running' => true]);
110
111
            return $timer[0]['id'] ?? false;
112
        } catch (\Exception $e) {
113
            return false;
114
        }
115
    }
116
117
    public function continueTimer($timerId)
118
    {
119
        $timer = $this->client->timeEntries()->restart($timerId);
120
121
        return $timer['id'] ?? false;
122
    }
123
124
    public function deleteTimer($timerId)
125
    {
126
        try {
127
            $this->client->timeEntries()->remove($timerId);
128
        } catch (NotFoundException $e) {
129
            return false;
130
        }
131
132
        return true;
133
    }
134
135
    protected function convertToPastTimers($harvestTimers)
136
    {
137
        return array_map(function ($harvestTimer) {
138
            return $this->buildPastTimerObject($harvestTimer);
139
        }, $harvestTimers);
140
    }
141
142
    protected function buildPastTimerObject($harvestTimer)
143
    {
144
        $pastTimer['id'] = $harvestTimer['id'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$pastTimer was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pastTimer = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
145
        $pastTimer['description'] = $harvestTimer['notes'];
146
        $pastTimer['project_id'] = $harvestTimer['project']['id'];
147
        $pastTimer['project_name'] = $harvestTimer['project']['name'];
148
        $pastTimer['tags'] = $harvestTimer['task']['name'];
149
        $pastTimer['duration'] = CarbonInterval::seconds(
150
            floor($harvestTimer['hours'] * 3600)
151
        )->cascade()->format('%H:%I:%S');
152
153
        return (object) $pastTimer;
154
    }
155
}
156