Test Setup Failed
Push — master ( fa3399...eb0696 )
by Matthieu
01:43
created

SyncTimings::buildTimeLog()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace Syncer\Command;
4
5
use Syncer\Dto\InvoiceNinja\Task;
6
use Syncer\Dto\Toggl\TimeEntry;
7
use Syncer\InvoiceNinja\Client as InvoiceNinjaClient;
8
use Syncer\Toggl\ReportsClient;
9
use Syncer\Toggl\TogglClient;
10
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Style\SymfonyStyle;
15
16
/**
17
 * Class SyncTimings
18
 * @package Syncer\Command
19
 *
20
 * @author Matthieu Calie <[email protected]>
21
 */
22
class SyncTimings extends Command
23
{
24
    /**
25
     * @var SymfonyStyle
26
     */
27
    private $io;
28
29
    /**
30
     * @var TogglClient
31
     */
32
    private $togglClient;
33
34
    /**
35
     * @var ReportsClient
36
     */
37
    private $reportsClient;
38
39
    /**
40
     * @var InvoiceNinjaClient
41
     */
42
    private $invoiceNinjaClient;
43
44
    /**
45
     * @var array
46
     */
47
    private $clients;
48
49
    /**
50
     * @var array
51
     */
52
    private $projects;
53
54
    /**
55
     * SyncTimings constructor.
56
     *
57
     * @param TogglClient $togglClient
58
     * @param ReportsClient $reportsClient
59
     * @param InvoiceNinjaClient $invoiceNinjaClient
60
     * @param array $clients
61
     * @param array $projects
62
     */
63
    public function __construct(
64
        TogglClient $togglClient,
65
        ReportsClient $reportsClient,
66
        InvoiceNinjaClient $invoiceNinjaClient,
67
        $clients,
68
        $projects
69
    ) {
70
        $this->togglClient = $togglClient;
71
        $this->reportsClient = $reportsClient;
72
        $this->invoiceNinjaClient = $invoiceNinjaClient;
73
        $this->clients = $clients;
74
        $this->projects = $projects;
75
76
        parent::__construct();
77
    }
78
79
    /**
80
     * Configure the command
81
     */
82
    protected function configure()
83
    {
84
        $this
85
            ->setName('sync:timings')
86
            ->setDescription('Syncs timings from toggl to invoiceninja')
87
        ;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    protected function execute(InputInterface $input, OutputInterface $output)
94
    {
95
        $this->io = new SymfonyStyle($input, $output);
96
        $workspaces = $this->togglClient->getWorkspaces();
97
98
        foreach ($workspaces as $workspace) {
0 ignored issues
show
Bug introduced by
The expression $workspaces of type object|array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
99
            $detailedReport = $this->reportsClient->getDetailedReport($workspace->getId());
100
101
            foreach($detailedReport->getData() as $timeEntry) {
102
                $timeEntrySent = false;
103
104
                // Log the entry if the client key exists
105
                if ($this->timeEntryCanBeLoggedByConfig($this->clients, $timeEntry->getClient(), $timeEntrySent)) {
106
                    $this->logTask($timeEntry, $this->clients, $timeEntry->getClient());
107
108
                    $timeEntrySent = true;
109
                }
110
111
                // Log the entry if the project key exists
112
                if ($this->timeEntryCanBeLoggedByConfig($this->projects, $timeEntry->getProject(), $timeEntrySent)) {
113
                    $this->logTask($timeEntry, $this->projects, $timeEntry->getProject());
114
115
                    $timeEntrySent = true;
116
                }
117
118
                if ($timeEntrySent) {
119
                    $this->io->success('TimeEntry ('. $timeEntry->getDescription() . ') sent to toggl');
120
                }
121
            }
122
        }
123
    }
124
125
    /**
126
     * @param $config
127
     * @param $entryKey
128
     * @param $hasAlreadyBeenSent
129
     *
130
     * @return bool
131
     */
132
    private function timeEntryCanBeLoggedByConfig($config, $entryKey, $hasAlreadyBeenSent)
133
    {
134
        if ($hasAlreadyBeenSent) {
135
            return false;
136
        }
137
138
        return (is_array($config) && array_key_exists($entryKey, $config));
139
    }
140
141
    /**
142
     * @param TimeEntry $entry
143
     * @param array $config
144
     * @param $key
145
     */
146
    private function logTask(TimeEntry $entry, array $config, $key)
147
    {
148
        $task = new Task();
149
150
        $task->setDescription($this->buildTaskDescription($entry));
151
        $task->setTimeLog($this->buildTimeLog($entry));
152
        $task->setClientId($config[$key]);
153
154
        $this->invoiceNinjaClient->saveNewTask($task);
155
    }
156
157
    /**
158
     * @param TimeEntry $entry
159
     *
160
     * @return string
161
     */
162
    private function buildTaskDescription(TimeEntry $entry)
163
    {
164
        $description = '';
165
166
        if ($entry->getProject()) {
167
            $description .= $entry->getProject() . ': ';
168
        }
169
170
        $description .= $entry->getDescription();
171
172
        return $description;
173
    }
174
175
    /**
176
     * @param TimeEntry $entry
177
     *
178
     * @return string
179
     */
180
    private function buildTimeLog(TimeEntry $entry)
181
    {
182
        $timeLog = [
183
            $entry->getStart()->getTimestamp(),
184
            $entry->getEnd()->getTimestamp(),
185
        ];
186
187
        return \GuzzleHttp\json_encode($timeLog);
188
    }
189
}
190