Skip to content

Commit c0cc82d

Browse files
committed
Added more methods and stuff
1 parent 571c06d commit c0cc82d

10 files changed

Lines changed: 232 additions & 21 deletions

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"require": {
77
"ext-simplexml": "*",
88
"psr/cache": "^2.0 || ^3.0",
9+
"swaggest/json-diff": "^3.12",
910
"symfony/cache": "^6.4 || ^7.4 || ^8.1",
1011
"symfony/console": "^6.4 || ^7.4 || ^8.1",
1112
"symfony/http-client": "^6.4 || ^7.4 || ^8.1",

mago.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@ too-many-methods = {
5555

5656
# Our API client is not really that complex …
5757
cyclomatic-complexity = {
58-
threshold = 31
58+
threshold = 38
5959
}
6060

6161
too-many-properties = {
6262
threshold = 11
6363
}
6464

65+
kan-defect = {
66+
threshold = 1.92
67+
}
68+
6569
[analyzer]
6670
plugins = []
6771
find-unused-definitions = true

src/Client/ApiClient.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66

77
use ItkDev\F2ApiClient\Exception\ApiException;
88
use ItkDev\F2ApiClient\Exception\RuntimeException;
9+
use ItkDev\F2ApiClient\Model\AbstractF2Item;
910
use ItkDev\F2ApiClient\Model\AbstractItem;
1011
use ItkDev\F2ApiClient\Model\Atom;
1112
use ItkDev\F2ApiClient\Model\CaseFile;
13+
use ItkDev\F2ApiClient\Model\Collection;
1214
use ItkDev\F2ApiClient\Model\Document;
1315
use ItkDev\F2ApiClient\Model\Matter;
1416
use Psr\Cache\CacheItemInterface;
1517
use Psr\Cache\CacheItemPoolInterface;
1618
use Psr\Log\LoggerAwareTrait;
1719
use Psr\Log\LoggerTrait;
20+
use Swaggest\JsonDiff\JsonDiff;
1821
use Symfony\Component\Cache\Adapter\ProxyAdapter;
1922
use Symfony\Component\HttpClient\HttpClient;
2023
use Symfony\Component\HttpFoundation\Request;
@@ -163,6 +166,27 @@ public function caseCreate(array $caseData): CaseFile
163166
return $this->createItemResult($response, CaseFile::class);
164167
}
165168

169+
public function caseFileUpdate(CaseFile $caseFile, CaseFile $updatedCaseFile): bool
170+
{
171+
$url = $caseFile->links->getLinkUrl('self');
172+
$diff = new JsonDiff(
173+
$caseFile->jsonSerialize(),
174+
$updatedCaseFile->jsonSerialize(),
175+
// The F2 API does not support "test" in JSON Patch
176+
options: JsonDiff::SKIP_TEST_OPS,
177+
);
178+
$response = $this->request(Request::METHOD_PATCH, $url, [
179+
'json' => $diff->getPatch()->jsonSerialize(),
180+
]);
181+
182+
if (Response::HTTP_OK !== $response->getStatusCode()) {
183+
$message = sprintf('Cannot update case %s', $caseFile);
184+
throw $this->createRuntimeException($message, response: $response);
185+
}
186+
187+
return true;
188+
}
189+
166190
/**
167191
* @return Atom[]
168192
*/
@@ -244,6 +268,26 @@ public function matterCreate(array $matterData, ?CaseFile $case = null): Matter
244268
return $this->createItemResult($response, Matter::class);
245269
}
246270

271+
public function matterUpdate(Matter $matter, Matter $updatedMatter): bool
272+
{
273+
$url = $matter->links->getLinkUrl('self');
274+
$diff = new JsonDiff(
275+
$matter->jsonSerialize(),
276+
$updatedMatter->jsonSerialize(),
277+
options: JsonDiff::SKIP_TEST_OPS,
278+
);
279+
$response = $this->request(Request::METHOD_PATCH, $url, [
280+
'json' => $diff->getPatch()->jsonSerialize(),
281+
]);
282+
283+
if (Response::HTTP_OK !== $response->getStatusCode()) {
284+
$message = sprintf('Cannot update matter %s', $matter);
285+
throw $this->createRuntimeException($message, response: $response);
286+
}
287+
288+
return true;
289+
}
290+
247291
public function documentById(int $id): Document
248292
{
249293
$url = $this->getRequestUrl('http://cbrain.com/casefile/rel/document-by-id', [
@@ -258,6 +302,18 @@ public function documentById(int $id): Document
258302
return $this->createItemResult($response, Document::class);
259303
}
260304

305+
public function getDocumentContent(Document $document): ResponseInterface
306+
{
307+
$url = $document->links->getLinkUrl('http://cbrain.com/casefile/rel/content');
308+
$response = $this->request(Request::METHOD_GET, $url);
309+
310+
if (Response::HTTP_OK !== $response->getStatusCode()) {
311+
throw $this->createApiException($response);
312+
}
313+
314+
return $response;
315+
}
316+
261317
public function documentCreate(string $filename, array $documentData, Matter $matter): Document
262318
{
263319
$linkName = 'http://cbrain.com/casefile/rel/create-document';
@@ -337,6 +393,13 @@ protected function getAccessToken(): array
337393

338394
protected function request(string $method, string $path, array $options = []): ResponseInterface
339395
{
396+
if (Request::METHOD_PATCH === $method && array_key_exists('json', $options)) {
397+
if (!array_key_exists('headers', $options) || !is_array($options['headers'])) {
398+
$options['headers'] = [];
399+
}
400+
$options['headers']['content-type'] = 'application/json-patch';
401+
}
402+
340403
$accessToken = $this->getAccessToken();
341404

342405
try {
@@ -555,4 +618,14 @@ private function logException(RuntimeException $exception): RuntimeException
555618

556619
return $exception;
557620
}
621+
622+
public function getDown(AbstractF2Item $item): Collection
623+
{
624+
$url = $item->links->getLinkUrl('down');
625+
$response = $this->request(Request::METHOD_GET, $url);
626+
627+
$sxe = new \SimpleXMLElement($response->getContent());
628+
629+
return Collection::fromSimpleXMLElement($sxe);
630+
}
558631
}

src/Model/AbstractF2Item.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ abstract class AbstractF2Item extends AbstractItem implements \Stringable
1111
public ?int $id = null;
1212
public Links $links;
1313

14+
public function __construct()
15+
{
16+
$this->links = new Links([]);
17+
}
18+
1419
// @mago-ignore analysis:non-documented-property
1520
#[\Override]
1621
public function setFromSimpleXMLElement(\SimpleXMLElement $sxe): static
@@ -35,4 +40,9 @@ public function jsonSerialize(): array
3540
'links' => $this->links->jsonSerialize(),
3641
];
3742
}
43+
44+
protected function serializeDateTime(?\DateTimeImmutable $dateTime): ?string
45+
{
46+
return $dateTime?->format(\DateTimeInterface::ATOM);
47+
}
3848
}

src/Model/CaseFile.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ public function __toString(): string
6262
public function jsonSerialize(): array
6363
{
6464
return [
65-
'caseNumber' => $this->caseNumber,
66-
'title' => $this->title,
67-
'closed' => $this->closed,
68-
'journalPlan' => $this->journalPlan->jsonSerialize(),
69-
'processInstruction' => $this->processInstruction->jsonSerialize(),
70-
'deadline' => $this->deadline,
71-
'createdDate' => $this->createdDate,
72-
'modifiedDate' => $this->modifiedDate,
73-
'modifiedBy' => $this->modifiedBy->jsonSerialize(),
74-
'responsible' => $this->responsible?->jsonSerialize(),
75-
'matters' => array_map(static fn (Matter $matter) => $matter->jsonSerialize(), $this->matters),
65+
'CaseNumber' => $this->caseNumber,
66+
'Title' => $this->title,
67+
'Closed' => $this->closed,
68+
'JournalPlan' => $this->journalPlan->jsonSerialize(),
69+
'ProcessInstruction' => $this->processInstruction->jsonSerialize(),
70+
'Deadline' => $this->deadline,
71+
'CreatedDate' => $this->createdDate,
72+
'ModifiedDate' => $this->modifiedDate,
73+
'ModifiedBy' => $this->modifiedBy->jsonSerialize(),
74+
'Responsible' => $this->responsible?->jsonSerialize(),
75+
'Matters' => array_map(static fn (Matter $matter) => $matter->jsonSerialize(), $this->matters),
7676
] + parent::jsonSerialize();
7777
}
7878
}

src/Model/Collection.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ItkDev\F2ApiClient\Model;
6+
7+
use ItkDev\F2ApiClient\Model\Collection\Item;
8+
9+
/**
10+
* A (simple) collection.
11+
*/
12+
final class Collection extends AbstractF2Item
13+
{
14+
public string $title;
15+
/** @var Item[] */
16+
public array $items;
17+
18+
// @mago-ignore analysis:non-documented-property,mixed-property-access
19+
#[\Override]
20+
public function setFromSimpleXMLElement(\SimpleXMLElement $sxe): static
21+
{
22+
parent::setFromSimpleXMLElement($sxe);
23+
24+
$this->title = (string) $sxe->Title;
25+
$this->items = [];
26+
/** @var \SimpleXMLElement[] $items */
27+
$items = $sxe->Items->Item;
28+
foreach ($items as $item) {
29+
$this->items[] = Item::fromSimpleXMLElement($item);
30+
}
31+
32+
return $this;
33+
}
34+
35+
#[\Override]
36+
public function __toString(): string
37+
{
38+
return sprintf('%s (%s)', $this->title, $this->id);
39+
}
40+
41+
#[\Override]
42+
public function jsonSerialize(): array
43+
{
44+
return [
45+
'id' => $this->id,
46+
'title' => $this->title,
47+
'items' => array_map(static fn (Item $item) => $item->jsonSerialize(), $this->items),
48+
];
49+
}
50+
}

src/Model/Collection/Item.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ItkDev\F2ApiClient\Model\Collection;
6+
7+
use ItkDev\F2ApiClient\Model\AbstractF2Item;
8+
9+
final class Item extends AbstractF2Item implements \JsonSerializable
10+
{
11+
public string $title;
12+
13+
// @mago-ignore analysis:non-documented-property
14+
public function setFromSimpleXMLElement(\SimpleXMLElement $sxe): static
15+
{
16+
parent::setFromSimpleXMLElement($sxe);
17+
18+
$this->title = (string) $sxe->Title;
19+
20+
return $this;
21+
}
22+
23+
#[\Override]
24+
public function __toString(): string
25+
{
26+
return sprintf('Document %s (#%d)', $this->title, $this->id);
27+
}
28+
29+
#[\Override]
30+
public function jsonSerialize(): array
31+
{
32+
return [
33+
'Title' => $this->title,
34+
] + parent::jsonSerialize();
35+
}
36+
}

src/Model/Document.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,40 @@
66

77
final class Document extends AbstractF2Item
88
{
9+
public string $title;
10+
public ?string $description = null;
11+
public ?\DateTimeImmutable $createdDate = null;
12+
public ?\DateTimeImmutable $modifiedDate = null;
13+
14+
// @mago-ignore analysis:non-documented-property,mixed-argument
15+
#[\Override]
16+
public function setFromSimpleXMLElement(\SimpleXMLElement $sxe): static
17+
{
18+
parent::setFromSimpleXMLElement($sxe);
19+
20+
$this->id = (int) $sxe->Id;
21+
$this->title = (string) $sxe->Title;
22+
$this->description = (string) $sxe->Description;
23+
$this->createdDate = $this->createDateTime($sxe->CreatedDate);
24+
$this->modifiedDate = $this->createDateTime($sxe->ModifiedDate);
25+
26+
return $this;
27+
}
28+
29+
#[\Override]
30+
public function __toString(): string
31+
{
32+
return sprintf('Document %s (#%d)', $this->title, $this->id);
33+
}
34+
35+
#[\Override]
36+
public function jsonSerialize(): array
37+
{
38+
return [
39+
'Title' => $this->title,
40+
'Description' => $this->description,
41+
'CreatedDate' => $this->serializeDateTime($this->createdDate),
42+
'ModifiedDate' => $this->serializeDateTime($this->modifiedDate),
43+
] + parent::jsonSerialize();
44+
}
945
}

src/Model/F2Item/Links.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public static function fromSimpleXMLElement(\SimpleXMLElement $sxe): static
3232
foreach ($attributes as $key => $value) {
3333
$link[$key] = (string) $value;
3434
}
35+
/** @var Link $link */
3536
if (array_key_exists('rel', $link)) {
3637
$links[$link['rel']] = $link;
3738
}

src/Model/Matter.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ public function __toString(): string
5151
public function jsonSerialize(): array
5252
{
5353
return [
54-
'matterNumber' => $this->matterNumber,
55-
'title' => $this->title,
56-
'type' => $this->type,
57-
'caseNumber' => $this->caseNumber,
58-
'createdDate' => $this->createdDate,
59-
'modifiedDate' => $this->modifiedDate,
60-
'createdBy' => $this->createdBy->jsonSerialize(),
61-
'modifiedBy' => $this->modifiedBy->jsonSerialize(),
62-
'responsible' => $this->responsible?->jsonSerialize(),
54+
'MatterNumber' => $this->matterNumber,
55+
'Title' => $this->title,
56+
'Type' => $this->type,
57+
'CaseNumber' => $this->caseNumber,
58+
'CreatedDate' => $this->serializeDateTime($this->createdDate),
59+
'ModifiedDate' => $this->serializeDateTime($this->modifiedDate),
60+
'CreatedBy' => $this->createdBy->jsonSerialize(),
61+
'ModifiedBy' => $this->modifiedBy->jsonSerialize(),
62+
'Responsible' => $this->responsible?->jsonSerialize(),
6363
] + parent::jsonSerialize();
6464
}
6565
}

0 commit comments

Comments
 (0)