HalJsonRenderer::arrayForJson()   B
last analyzed

Complexity

Conditions 7
Paths 13

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.5706
c 0
b 0
f 0
cc 7
nc 13
nop 1
1
<?php
2
/**
3
 * This file is part of the Hal library
4
 *
5
 * (c) Ben Longden <[email protected]
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @package Nocarrier
11
 */
12
namespace Nocarrier;
13
14
/**
15
 * HalJsonRenderer
16
 *
17
 * @uses HalRenderer
18
 * @package Nocarrier
19
 * @author Ben Longden <[email protected]>
20
 */
21
class HalJsonRenderer implements HalRenderer
22
{
23
    /**
24
     * Render.
25
     *
26
     * @param \Nocarrier\Hal $resource
27
     * @param bool $pretty
28
     * @param bool $encode
29
     * @return string|array
30
     */
31
    public function render(Hal $resource, $pretty, $encode = true)
32
    {
33
        $options = 0;
34
        if (version_compare(PHP_VERSION, '5.4.0') >= 0 and $pretty) {
35
            $options = JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT;
36
        }
37
38
        $arrayForJson = $this->arrayForJson($resource);
39
        if ($encode) {
40
            return json_encode($arrayForJson, $options);
41
        }
42
43
        return $arrayForJson;
44
    }
45
46
    /**
47
     * Return an array (compatible with the hal+json format) representing
48
     * associated links.
49
     *
50
     * @param mixed $uri
51
     * @param array $links
52
     * @return array
53
     */
54
    protected function linksForJson($uri, $links, $arrayLinkRels)
55
    {
56
        $data = array();
57
        if (!is_null($uri)) {
58
            $data['self'] = array('href' => $uri);
59
        }
60
        foreach ($links as $rel => $links) {
61
            if (count($links) === 1 && $rel !== 'curies' && !in_array($rel, $arrayLinkRels)) {
62
                $data[$rel] = array('href' => $links[0]->getUri());
63
                foreach ($links[0]->getAttributes() as $attribute => $value) {
64
                    $data[$rel][$attribute] = $value;
65
                }
66
            } else {
67
                $data[$rel] = array();
68
                foreach ($links as $link) {
69
                    $item = array('href' => $link->getUri());
70
                    foreach ($link->getAttributes() as $attribute => $value) {
71
                        $item[$attribute] = $value;
72
                    }
73
                    $data[$rel][] = $item;
74
                }
75
            }
76
        }
77
78
        return $data;
79
    }
80
81
    /**
82
     * Return an array (compatible with the hal+json format) representing
83
     * associated resources.
84
     *
85
     * @param mixed $resources
86
     * @return array
87
     */
88
    protected function resourcesForJson($resources)
89
    {
90
        if (!is_array($resources)) {
91
            return $this->arrayForJson($resources);
92
        }
93
94
        $data = array();
95
96
        foreach ($resources as $resource) {
97
            $res = $this->arrayForJson($resource);
98
99
            if (!empty($res)) {
100
                $data[] = $res;
101
            }
102
        }
103
104
        return $data;
105
    }
106
107
    /**
108
     * Remove the @ prefix from keys that denotes an attribute in XML. This
109
     * cannot be represented in JSON, so it's effectively ignored.
110
     *
111
     * @param array $data
112
     *   The array to strip @ from the keys.
113
     * @return array
114
     */
115
    protected function stripAttributeMarker(array $data)
116
    {
117
        foreach ($data as $key => $value) {
118
            if (substr($key, 0, 5) == '@xml:') {
119
                $data[substr($key, 5)] = $value;
120
                unset ($data[$key]);
121
            } elseif (substr($key, 0, 1) == '@') {
122
                $data[substr($key, 1)] = $value;
123
                unset ($data[$key]);
124
            }
125
126
            if (is_array($value)) {
127
                $data[$key] = $this->stripAttributeMarker($value);
128
            }
129
        }
130
131
        return $data;
132
    }
133
134
    /**
135
     * Return an array (compatible with the hal+json format) representing the
136
     * complete response.
137
     *
138
     * @param \Nocarrier\Hal $resource
139
     * @return array
140
     */
141
    protected function arrayForJson(Hal $resource = null)
142
    {
143
        if ($resource == null) {
144
            return array();
145
        }
146
147
        $data = $resource->getData();
148
        if ($resource->getShouldStripAttributes()) {
149
            $data = $this->stripAttributeMarker($data);
150
        }
151
152
        $links = $this->linksForJson($resource->getUri(), $resource->getLinks(), $resource->getArrayLinkRels());
153
        if (count($links)) {
154
            $data['_links'] = $links;
155
        }
156
157
        foreach ($resource->getRawResources() as $rel => $resources) {
158
            if (count($resources) === 1 && !in_array($rel, $resource->getArrayResourceRels())) {
159
                $resources = $resources[0];
160
            }
161
162
            $data['_embedded'][$rel] = $this->resourcesForJson($resources);
163
        }
164
165
        return $data;
166
    }
167
}
168