LinksFirstXmlHalSerializer::serializeLinks()   B
last analyzed

Complexity

Conditions 8
Paths 9

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 8
eloc 22
c 3
b 0
f 0
nc 9
nop 3
dl 0
loc 39
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stratadox\CardGame\Infrastructure\Rest\Serializer;
6
7
use DOMElement;
8
use DOMNode;
9
use DOMNodeList;
10
use Hateoas\Model\Embedded;
11
use Hateoas\Serializer\SerializerInterface;
12
use JMS\Serializer\SerializationContext;
13
use JMS\Serializer\Visitor\SerializationVisitorInterface;
14
use JMS\Serializer\XmlSerializationVisitor;
15
use LogicException;
16
use RuntimeException;
17
18
class LinksFirstXmlHalSerializer implements SerializerInterface
19
{
20
    /** @var SerializerInterface */
21
    private $embeddedSerializer;
22
23
    public function __construct(SerializerInterface $embeddedSerializer)
24
    {
25
        $this->embeddedSerializer = $embeddedSerializer;
26
    }
27
28
    public function serializeLinks(
29
        array $links,
30
        SerializationVisitorInterface $visitor,
31
        SerializationContext $context
32
    ): void {
33
        if (!$visitor instanceof XmlSerializationVisitor) {
34
            throw new LogicException(
35
                'XML Serializers can be visited only by Xml Visitors'
36
            );
37
        }
38
        $node = $visitor->getCurrentNode();
39
        if (!$node instanceof DOMElement) {
40
            throw new RuntimeException('Nothing to serialize!');
41
        }
42
43
        foreach ($links as $link) {
44
            if ('self' === $link->getRel()) {
45
                foreach ($link->getAttributes() as $key => $value) {
46
                    $node->setAttribute($key, $value);
47
                }
48
49
                $node->setAttribute('href', $link->getHref());
50
51
                continue;
52
            }
53
54
            $linkNode = $visitor->getDocument()->createElement('link');
55
            $child = $this->firstNonLinkChild($node->childNodes);
56
            if ($child === null) {
57
                $node->appendChild($linkNode);
58
            } else {
59
                $node->insertBefore($linkNode, $child);
60
            }
61
62
            $linkNode->setAttribute('rel', $link->getRel());
63
            $linkNode->setAttribute('href', $link->getHref());
64
65
            foreach ($link->getAttributes() as $attributeName => $attributeValue) {
66
                $linkNode->setAttribute($attributeName, $attributeValue);
67
            }
68
        }
69
    }
70
71
    /**
72
     * @param Embedded[] $embeddeds
73
     */
74
    public function serializeEmbeddeds(array $embeddeds, SerializationVisitorInterface $visitor, SerializationContext $context): void
75
    {
76
        $this->embeddedSerializer->serializeEmbeddeds($embeddeds, $visitor, $context);
77
    }
78
79
    private function firstNonLinkChild(DOMNodeList $nodes): ?DOMNode
80
    {
81
        /** @var DOMNode $node */
82
        foreach ($nodes as $node) {
83
            if ($node->nodeName !== 'link') {
84
                return $node;
85
            }
86
        }
87
        return null;
88
    }
89
}
90