1 | <?php |
||
2 | /** |
||
3 | * SpectreRoutine.php |
||
4 | * Copyright (c) 2017 [email protected] |
||
5 | * |
||
6 | * This file is part of Firefly III. |
||
7 | * |
||
8 | * Firefly III is free software: you can redistribute it and/or modify |
||
9 | * it under the terms of the GNU General Public License as published by |
||
10 | * the Free Software Foundation, either version 3 of the License, or |
||
11 | * (at your option) any later version. |
||
12 | * |
||
13 | * Firefly III is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |
||
20 | */ |
||
21 | declare(strict_types=1); |
||
22 | |||
23 | namespace FireflyIII\Import\Routine; |
||
24 | |||
25 | use Carbon\Carbon; |
||
26 | use DB; |
||
27 | use Exception; |
||
28 | use FireflyIII\Exceptions\FireflyException; |
||
29 | use FireflyIII\Import\Object\ImportJournal; |
||
30 | use FireflyIII\Import\Storage\ImportStorage; |
||
31 | use FireflyIII\Models\ImportJob; |
||
32 | use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; |
||
33 | use FireflyIII\Repositories\Tag\TagRepositoryInterface; |
||
34 | use FireflyIII\Services\Spectre\Exception\SpectreException; |
||
35 | use FireflyIII\Services\Spectre\Object\Account; |
||
36 | use FireflyIII\Services\Spectre\Object\Customer; |
||
37 | use FireflyIII\Services\Spectre\Object\Login; |
||
38 | use FireflyIII\Services\Spectre\Object\Token; |
||
39 | use FireflyIII\Services\Spectre\Object\Transaction; |
||
40 | use FireflyIII\Services\Spectre\Request\CreateTokenRequest; |
||
41 | use FireflyIII\Services\Spectre\Request\ListAccountsRequest; |
||
42 | use FireflyIII\Services\Spectre\Request\ListCustomersRequest; |
||
43 | use FireflyIII\Services\Spectre\Request\ListLoginsRequest; |
||
44 | use FireflyIII\Services\Spectre\Request\ListTransactionsRequest; |
||
45 | use FireflyIII\Services\Spectre\Request\NewCustomerRequest; |
||
46 | use Illuminate\Support\Collection; |
||
47 | use Log; |
||
48 | use Preferences; |
||
49 | |||
50 | /** |
||
51 | * Class FileRoutine |
||
52 | */ |
||
53 | class SpectreRoutine implements RoutineInterface |
||
54 | { |
||
55 | /** @var Collection */ |
||
56 | public $errors; |
||
57 | /** @var Collection */ |
||
58 | public $journals; |
||
59 | /** @var int */ |
||
60 | public $lines = 0; |
||
61 | /** @var ImportJob */ |
||
62 | private $job; |
||
63 | |||
64 | /** @var ImportJobRepositoryInterface */ |
||
65 | private $repository; |
||
66 | |||
67 | /** |
||
68 | * ImportRoutine constructor. |
||
69 | */ |
||
70 | public function __construct() |
||
71 | { |
||
72 | $this->journals = new Collection; |
||
73 | $this->errors = new Collection; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * @return Collection |
||
78 | */ |
||
79 | public function getErrors(): Collection |
||
80 | { |
||
81 | return $this->errors; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * @return Collection |
||
86 | */ |
||
87 | public function getJournals(): Collection |
||
88 | { |
||
89 | return $this->journals; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * @return int |
||
94 | */ |
||
95 | public function getLines(): int |
||
96 | { |
||
97 | return $this->lines; |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * A Spectre job that ends up here is either "configured" or "running", and will be set to "running" |
||
102 | * when it is "configured". |
||
103 | * |
||
104 | * Job has several stages, stored in extended status key 'stage' |
||
105 | * |
||
106 | * initial: just begun, nothing happened. action: get a customer and a token. Next status: has-token |
||
107 | * has-token: redirect user to sandstorm, make user login. set job to: user-logged-in |
||
108 | * user-logged-in: customer has an attempt. action: analyse/get attempt and go for next status. |
||
109 | * if attempt failed: job status is error, save a warning somewhere? |
||
110 | * if success, try to get accounts. Save in config key 'accounts'. set status: have-accounts and "configuring" |
||
111 | * |
||
112 | * have-accounts: make user link accounts and select accounts to import from. |
||
113 | * |
||
114 | * If job is "configuring" and stage "have-accounts" then present the accounts and make user link them to |
||
115 | * own asset accounts. Store this mapping, set config to "have-account-mapping" and job status configured". |
||
116 | * |
||
117 | * have-account-mapping: start downloading transactions? |
||
118 | * |
||
119 | * |
||
120 | * @return bool |
||
121 | * |
||
122 | * @throws FireflyException |
||
123 | * @throws SpectreException |
||
124 | * @throws \Illuminate\Container\EntryNotFoundException |
||
125 | */ |
||
126 | public function run(): bool |
||
127 | { |
||
128 | if ('configured' === $this->getStatus()) { |
||
129 | $this->repository->updateStatus($this->job, 'running'); |
||
130 | } |
||
131 | Log::info(sprintf('Start with import job %s using Spectre.', $this->job->key)); |
||
132 | set_time_limit(0); |
||
133 | |||
134 | // check if job has token first! |
||
135 | $stage = $this->getConfig()['stage'] ?? 'unknown'; |
||
136 | |||
137 | switch ($stage) { |
||
138 | case 'initial': |
||
0 ignored issues
–
show
|
|||
139 | // get customer and token: |
||
140 | $this->runStageInitial(); |
||
141 | break; |
||
142 | case 'has-token': |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.
Loading history...
|
|||
143 | // import routine does nothing at this point: |
||
144 | break; |
||
145 | case 'user-logged-in': |
||
146 | $this->runStageLoggedIn(); |
||
147 | break; |
||
148 | case 'have-account-mapping': |
||
149 | $this->runStageHaveMapping(); |
||
150 | break; |
||
151 | default: |
||
152 | throw new FireflyException(sprintf('Cannot handle stage %s', $stage)); |
||
153 | } |
||
154 | |||
155 | return true; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * @param ImportJob $job |
||
160 | */ |
||
161 | public function setJob(ImportJob $job) |
||
162 | { |
||
163 | $this->job = $job; |
||
164 | $this->repository = app(ImportJobRepositoryInterface::class); |
||
165 | $this->repository->setUser($job->user); |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * @return Customer |
||
170 | * |
||
171 | * @throws \FireflyIII\Exceptions\FireflyException |
||
172 | * @throws \FireflyIII\Services\Spectre\Exception\SpectreException |
||
173 | * @throws \Illuminate\Container\EntryNotFoundException |
||
174 | */ |
||
175 | protected function createCustomer(): Customer |
||
176 | { |
||
177 | $newCustomerRequest = new NewCustomerRequest($this->job->user); |
||
178 | $customer = null; |
||
179 | try { |
||
180 | $newCustomerRequest->call(); |
||
181 | $customer = $newCustomerRequest->getCustomer(); |
||
182 | } catch (Exception $e) { |
||
183 | // already exists, must fetch customer instead. |
||
184 | Log::warning(sprintf('Customer exists already for user, fetch it: %s', $e->getMessage())); |
||
185 | } |
||
186 | if (null === $customer) { |
||
187 | $getCustomerRequest = new ListCustomersRequest($this->job->user); |
||
188 | $getCustomerRequest->call(); |
||
189 | $customers = $getCustomerRequest->getCustomers(); |
||
190 | /** @var Customer $current */ |
||
191 | foreach ($customers as $current) { |
||
192 | if ('default_ff3_customer' === $current->getIdentifier()) { |
||
193 | $customer = $current; |
||
194 | break; |
||
195 | } |
||
196 | } |
||
197 | } |
||
198 | |||
199 | Preferences::setForUser($this->job->user, 'spectre_customer', $customer->toArray()); |
||
200 | |||
201 | return $customer; |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @return Customer |
||
206 | * |
||
207 | * @throws FireflyException |
||
208 | * @throws SpectreException |
||
209 | * @throws \Illuminate\Container\EntryNotFoundException |
||
210 | */ |
||
211 | protected function getCustomer(): Customer |
||
212 | { |
||
213 | $config = $this->getConfig(); |
||
214 | if (null !== $config['customer']) { |
||
215 | $customer = new Customer($config['customer']); |
||
216 | |||
217 | return $customer; |
||
218 | } |
||
219 | |||
220 | $customer = $this->createCustomer(); |
||
221 | $config['customer'] = [ |
||
222 | 'id' => $customer->getId(), |
||
223 | 'identifier' => $customer->getIdentifier(), |
||
224 | 'secret' => $customer->getSecret(), |
||
225 | ]; |
||
226 | $this->setConfig($config); |
||
227 | |||
228 | return $customer; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * @param Customer $customer |
||
233 | * @param string $returnUri |
||
234 | * |
||
235 | * @return Token |
||
236 | * |
||
237 | * @throws \FireflyIII\Exceptions\FireflyException |
||
238 | * @throws \FireflyIII\Services\Spectre\Exception\SpectreException |
||
239 | * @throws \Illuminate\Container\EntryNotFoundException |
||
240 | */ |
||
241 | protected function getToken(Customer $customer, string $returnUri): Token |
||
242 | { |
||
243 | $request = new CreateTokenRequest($this->job->user); |
||
244 | $request->setUri($returnUri); |
||
245 | $request->setCustomer($customer); |
||
246 | $request->call(); |
||
247 | Log::debug('Call to get token is finished'); |
||
248 | |||
249 | return $request->getToken(); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * @throws FireflyException |
||
254 | * @throws SpectreException |
||
255 | * @throws \Illuminate\Container\EntryNotFoundException |
||
256 | */ |
||
257 | protected function runStageInitial(): void |
||
258 | { |
||
259 | Log::debug('In runStageInitial()'); |
||
260 | |||
261 | // create customer if user does not have one: |
||
262 | $customer = $this->getCustomer(); |
||
263 | Log::debug(sprintf('Customer ID is %s', $customer->getId())); |
||
264 | |||
265 | // use customer to request a token: |
||
266 | $uri = route('import.status', [$this->job->key]); |
||
267 | $token = $this->getToken($customer, $uri); |
||
268 | Log::debug(sprintf('Token is %s', $token->getToken())); |
||
269 | |||
270 | // update job, give it the token: |
||
271 | $config = $this->getConfig(); |
||
272 | $config['has-token'] = true; |
||
273 | $config['token'] = $token->getToken(); |
||
274 | $config['token-expires'] = $token->getExpiresAt()->format('U'); |
||
275 | $config['token-url'] = $token->getConnectUrl(); |
||
276 | $config['stage'] = 'has-token'; |
||
277 | $this->setConfig($config); |
||
278 | |||
279 | Log::debug('Job config is now', $config); |
||
280 | |||
281 | // update job, set status to "configuring". |
||
282 | $this->setStatus('configuring'); |
||
283 | Log::debug(sprintf('Job status is now %s', $this->job->status)); |
||
284 | $this->addStep(); |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * @throws FireflyException |
||
289 | * @throws SpectreException |
||
290 | * @throws \Illuminate\Container\EntryNotFoundException |
||
291 | */ |
||
292 | protected function runStageLoggedIn(): void |
||
293 | { |
||
294 | Log::debug('In runStageLoggedIn'); |
||
295 | // list all logins: |
||
296 | $customer = $this->getCustomer(); |
||
297 | $request = new ListLoginsRequest($this->job->user); |
||
298 | $request->setCustomer($customer); |
||
299 | $request->call(); |
||
300 | |||
301 | $logins = $request->getLogins(); |
||
302 | /** @var Login $final */ |
||
303 | $final = null; |
||
304 | // loop logins, find the latest with no error in it: |
||
305 | $time = 0; |
||
306 | /** @var Login $login */ |
||
307 | foreach ($logins as $login) { |
||
308 | $attempt = $login->getLastAttempt(); |
||
309 | $attemptTime = (int)$attempt->getCreatedAt()->format('U'); |
||
310 | if ($attemptTime > $time && null === $attempt->getFailErrorClass()) { |
||
311 | $time = $attemptTime; |
||
312 | $final = $login; |
||
313 | } |
||
314 | } |
||
315 | if (null === $final) { |
||
316 | Log::error('Could not find a valid login for this user.'); |
||
317 | $this->repository->addError($this->job, 0, 'Spectre connection failed. Did you use invalid credentials, press Cancel or failed the 2FA challenge?'); |
||
318 | $this->repository->setStatus($this->job, 'error'); |
||
319 | |||
320 | return; |
||
321 | } |
||
322 | $this->addStep(); |
||
323 | |||
324 | // list the users accounts using this login. |
||
325 | $accountRequest = new ListAccountsRequest($this->job->user); |
||
326 | $accountRequest->setLogin($login); |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
327 | $accountRequest->call(); |
||
328 | $accounts = $accountRequest->getAccounts(); |
||
329 | |||
330 | // store accounts in job: |
||
331 | $all = []; |
||
332 | /** @var Account $account */ |
||
333 | foreach ($accounts as $account) { |
||
334 | $all[] = $account->toArray(); |
||
335 | } |
||
336 | |||
337 | // update job: |
||
338 | $config = $this->getConfig(); |
||
339 | $config['accounts'] = $all; |
||
340 | $config['login'] = $login->toArray(); |
||
341 | $config['stage'] = 'have-accounts'; |
||
342 | |||
343 | $this->setConfig($config); |
||
344 | $this->setStatus('configuring'); |
||
345 | $this->addStep(); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * Shorthand method. |
||
350 | */ |
||
351 | private function addStep() |
||
352 | { |
||
353 | $this->repository->addStepsDone($this->job, 1); |
||
354 | } |
||
355 | |||
356 | /** |
||
357 | * Shorthand |
||
358 | * |
||
359 | * @param int $steps |
||
360 | */ |
||
361 | private function addTotalSteps(int $steps) |
||
362 | { |
||
363 | $this->repository->addTotalSteps($this->job, $steps); |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * @return array |
||
368 | */ |
||
369 | private function getConfig(): array |
||
370 | { |
||
371 | return $this->repository->getConfiguration($this->job); |
||
372 | } |
||
373 | |||
374 | /** |
||
375 | * Shorthand method. |
||
376 | * |
||
377 | * @return array |
||
378 | */ |
||
379 | private function getExtendedStatus(): array |
||
380 | { |
||
381 | return $this->repository->getExtendedStatus($this->job); |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Shorthand method. |
||
386 | * |
||
387 | * @return string |
||
388 | */ |
||
389 | private function getStatus(): string |
||
390 | { |
||
391 | return $this->repository->getStatus($this->job); |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * @param array $all |
||
396 | * |
||
397 | * @throws FireflyException |
||
398 | */ |
||
399 | private function importTransactions(array $all) |
||
400 | { |
||
401 | Log::debug('Going to import transactions'); |
||
402 | $collection = new Collection; |
||
403 | // create import objects? |
||
404 | foreach ($all as $accountId => $data) { |
||
405 | Log::debug(sprintf('Now at account #%d', $accountId)); |
||
406 | /** @var Transaction $transaction */ |
||
407 | foreach ($data['transactions'] as $transaction) { |
||
408 | Log::debug(sprintf('Now at transaction #%d', $transaction->getId())); |
||
409 | /** @var Account $account */ |
||
410 | $account = $data['account']; |
||
411 | $importJournal = new ImportJournal; |
||
412 | $importJournal->setUser($this->job->user); |
||
413 | $importJournal->asset->setDefaultAccountId($data['import_id']); |
||
414 | // call set value a bunch of times for various data entries: |
||
415 | $tags = []; |
||
416 | $tags[] = $transaction->getMode(); |
||
417 | $tags[] = $transaction->getStatus(); |
||
418 | if ($transaction->isDuplicated()) { |
||
419 | $tags[] = 'possibly-duplicated'; |
||
420 | } |
||
421 | $extra = $transaction->getExtra()->toArray(); |
||
422 | $notes = ''; |
||
423 | // double space for newline in Markdown. |
||
424 | $notes .= (string)trans('import.imported_from_account', ['account' => $account->getName()]) . ' ' . "\n"; |
||
425 | |||
426 | foreach ($extra as $key => $value) { |
||
427 | switch ($key) { |
||
428 | case 'account_number': |
||
429 | $importJournal->setValue(['role' => 'account-number', 'value' => $value]); |
||
430 | break; |
||
431 | case 'original_category': |
||
432 | case 'original_subcategory': |
||
433 | case 'customer_category_code': |
||
434 | case 'customer_category_name': |
||
435 | $tags[] = $value; |
||
436 | break; |
||
437 | case 'payee': |
||
438 | $importJournal->setValue(['role' => 'opposing-name', 'value' => $value]); |
||
439 | break; |
||
440 | case 'original_amount': |
||
441 | $importJournal->setValue(['role' => 'amount_foreign', 'value' => $value]); |
||
442 | break; |
||
443 | case 'original_currency_code': |
||
444 | $importJournal->setValue(['role' => 'foreign-currency-code', 'value' => $value]); |
||
445 | break; |
||
446 | default: |
||
447 | $notes .= $key . ': ' . $value . ' '; // for newline in Markdown. |
||
448 | } |
||
449 | } |
||
450 | // hash |
||
451 | $importJournal->setHash($transaction->getHash()); |
||
452 | |||
453 | // account ID (Firefly III account): |
||
454 | $importJournal->setValue(['role' => 'account-id', 'value' => $data['import_id'], 'mapped' => $data['import_id']]); |
||
455 | |||
456 | // description: |
||
457 | $importJournal->setValue(['role' => 'description', 'value' => $transaction->getDescription()]); |
||
458 | |||
459 | // date: |
||
460 | $importJournal->setValue(['role' => 'date-transaction', 'value' => $transaction->getMadeOn()->toIso8601String()]); |
||
461 | |||
462 | // amount |
||
463 | $importJournal->setValue(['role' => 'amount', 'value' => $transaction->getAmount()]); |
||
464 | $importJournal->setValue(['role' => 'currency-code', 'value' => $transaction->getCurrencyCode()]); |
||
465 | |||
466 | // various meta fields: |
||
467 | $importJournal->setValue(['role' => 'category-name', 'value' => $transaction->getCategory()]); |
||
468 | $importJournal->setValue(['role' => 'note', 'value' => $notes]); |
||
469 | $importJournal->setValue(['role' => 'tags-comma', 'value' => implode(',', $tags)]); |
||
470 | $collection->push($importJournal); |
||
471 | } |
||
472 | } |
||
473 | $this->addStep(); |
||
474 | Log::debug(sprintf('Going to try and store all %d them.', $collection->count())); |
||
475 | |||
476 | $this->addTotalSteps(7 * $collection->count()); |
||
477 | // try to store them (seven steps per transaction) |
||
478 | $storage = new ImportStorage; |
||
479 | |||
480 | $storage->setJob($this->job); |
||
481 | $storage->setDateFormat('Y-m-d\TH:i:sO'); |
||
482 | $storage->setObjects($collection); |
||
483 | $storage->store(); |
||
484 | Log::info('Back in importTransactions()'); |
||
485 | |||
486 | // link to tag |
||
487 | /** @var TagRepositoryInterface $repository */ |
||
488 | $repository = app(TagRepositoryInterface::class); |
||
489 | $repository->setUser($this->job->user); |
||
490 | $data = [ |
||
491 | 'tag' => trans('import.import_with_key', ['key' => $this->job->key]), |
||
492 | 'date' => new Carbon, |
||
493 | 'description' => null, |
||
494 | 'latitude' => null, |
||
495 | 'longitude' => null, |
||
496 | 'zoomLevel' => null, |
||
497 | 'tagMode' => 'nothing', |
||
498 | ]; |
||
499 | $tag = $repository->store($data); |
||
500 | $extended = $this->getExtendedStatus(); |
||
501 | $extended['tag'] = $tag->id; |
||
502 | $this->setExtendedStatus($extended); |
||
503 | |||
504 | Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag)); |
||
505 | Log::debug('Looping journals...'); |
||
506 | $journalIds = $storage->journals->pluck('id')->toArray(); |
||
507 | $tagId = $tag->id; |
||
508 | $this->addTotalSteps(count($journalIds)); |
||
509 | |||
510 | foreach ($journalIds as $journalId) { |
||
511 | Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId)); |
||
512 | DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]); |
||
513 | $this->addStep(); |
||
514 | } |
||
515 | Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $storage->journals->count(), $tag->id, $tag->tag)); |
||
516 | |||
517 | // set status to "finished"? |
||
518 | // update job: |
||
519 | $this->setStatus('finished'); |
||
520 | $this->addStep(); |
||
521 | |||
522 | } |
||
523 | |||
524 | /** |
||
525 | * @throws FireflyException |
||
526 | * @throws SpectreException |
||
527 | * @throws \Illuminate\Container\EntryNotFoundException |
||
528 | */ |
||
529 | private function runStageHaveMapping() |
||
530 | { |
||
531 | $config = $this->getConfig(); |
||
532 | $accounts = $config['accounts'] ?? []; |
||
533 | $all = []; |
||
534 | $count = 0; |
||
535 | /** @var array $accountArray */ |
||
536 | foreach ($accounts as $accountArray) { |
||
537 | $account = new Account($accountArray); |
||
538 | $importId = (int)($config['accounts-mapped'][$account->getId()] ?? 0.0); |
||
539 | $doImport = 0 !== $importId; |
||
540 | if (!$doImport) { |
||
541 | Log::debug(sprintf('Will NOT import from Spectre account #%d ("%s")', $account->getId(), $account->getName())); |
||
542 | continue; |
||
543 | } |
||
544 | // grab all transactions |
||
545 | $listTransactionsRequest = new ListTransactionsRequest($this->job->user); |
||
546 | $listTransactionsRequest->setAccount($account); |
||
547 | $listTransactionsRequest->call(); |
||
548 | $transactions = $listTransactionsRequest->getTransactions(); |
||
549 | $all[$account->getId()] = [ |
||
550 | 'account' => $account, |
||
551 | 'import_id' => $importId, |
||
552 | 'transactions' => $transactions, |
||
553 | ]; |
||
554 | $count += count($transactions); |
||
555 | } |
||
556 | Log::debug(sprintf('Total number of transactions: %d', $count)); |
||
557 | $this->addStep(); |
||
558 | |||
559 | $this->importTransactions($all); |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * Shorthand. |
||
564 | * |
||
565 | * @param array $config |
||
566 | */ |
||
567 | private function setConfig(array $config): void |
||
568 | { |
||
569 | $this->repository->setConfiguration($this->job, $config); |
||
570 | |||
571 | } |
||
572 | |||
573 | /** |
||
574 | * Shorthand method. |
||
575 | * |
||
576 | * @param array $extended |
||
577 | */ |
||
578 | private function setExtendedStatus(array $extended): void |
||
579 | { |
||
580 | $this->repository->setExtendedStatus($this->job, $extended); |
||
581 | |||
582 | } |
||
583 | |||
584 | /** |
||
585 | * Shorthand. |
||
586 | * |
||
587 | * @param string $status |
||
588 | */ |
||
589 | private function setStatus(string $status): void |
||
590 | { |
||
591 | $this->repository->setStatus($this->job, $status); |
||
592 | } |
||
593 | } |
||
594 |
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next
break
.There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.