Completed
Push — master ( 7e7292...b3bacf )
by Jesse
02:03
created

CondensedXmlFormatter   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 63
rs 10
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A toSimpleXML() 0 24 6
A __construct() 0 4 2
A in() 0 5 1
A from() 0 14 2
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\RestResource;
4
5
use SimpleXMLElement;
6
use Throwable;
7
use function is_array;
8
use function is_numeric;
9
use function sprintf;
10
use function str_replace;
11
12
final class CondensedXmlFormatter implements ResourceFormatter
13
{
14
    use LinkRetrieval;
15
16
    /** @var string */
17
    private $baseUri;
18
    /** @var Singularizer */
19
    private $singularizer;
20
21
    public function __construct(string $baseUri, Singularizer $singularizer = null)
22
    {
23
        $this->baseUri = $baseUri;
24
        $this->singularizer = $singularizer ?: BoogieSingularizer::default();
25
    }
26
27
    public static function in(
28
        string $locale,
29
        string $baseUri
30
    ): ResourceFormatter {
31
        return new self($baseUri, BoogieSingularizer::in($locale));
32
    }
33
34
    public function from(RestResource $resource): string
35
    {
36
        $xml = new SimpleXMLElement(sprintf(
37
            '<?xml version="1.0"?><%s />',
38
            $resource->name()
39
        ));
40
        try {
41
            $this->toSimpleXML(
42
                $resource->body() + $this->linksOf($resource, $this->baseUri),
43
                $xml
44
            );
45
            return (string) $xml->asXML();
46
        } catch (Throwable $exception) {
47
            throw CannotFormatXml::because($resource, $exception);
48
        }
49
    }
50
51
    private function toSimpleXML(
52
        array $input,
53
        SimpleXMLElement $parent,
54
        bool $alreadySingularized = false
55
    ): void {
56
        foreach ($input as $key => $value) {
57
58
            if (is_numeric($key)) {
59
                $name = $alreadySingularized ?
60
                    'item' : $this->singularizer->convert($parent->getName());
61
                $singularized = true;
62
            } else {
63
                $name = str_replace(['<', '>'], '', (string) $key);
64
                $singularized = false;
65
            }
66
67
            if (is_array($value)) {
68
                $node = $parent->addChild($name);
69
                $this->toSimpleXML($value, $node, $singularized);
70
            } elseif ($singularized) {
71
                $child = $parent->addChild($name);
72
                $child->addAttribute('value', (string) $value);
73
            } else {
74
                $parent->addAttribute($name, (string) $value);
75
            }
76
77
        }
78
    }
79
}
80