DataAttributesHelper   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 7
Bugs 1 Features 1
Metric Value
wmc 26
c 7
b 1
f 1
lcom 1
cbo 1
dl 0
loc 170
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A recursiveSetKeysToUnderScore() 0 13 3
D setResponseDataAttributes() 0 34 10
A transformToValidMemberName() 0 9 1
A isScalarValue() 0 6 3
D containsClassIdentifierKey() 0 25 9
1
<?php
2
3
/**
4
 * Author: Nil Portugués Calderó <[email protected]>
5
 * Date: 7/25/15
6
 * Time: 5:05 PM.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace NilPortugues\Api\JsonApi\Helpers;
12
13
use NilPortugues\Api\JsonApi\JsonApiTransformer;
14
use NilPortugues\Api\Transformer\Helpers\RecursiveFormatterHelper;
15
use NilPortugues\Serializer\Serializer;
16
17
/**
18
 * Class DataAttributesHelper.
19
 */
20
class DataAttributesHelper
21
{
22
    /**
23
     * @link http://jsonapi.org/format/#document-member-names-reserved-characters
24
     *
25
     * @var array
26
     */
27
    protected static $forbiddenMemberNameCharacters = [
28
        '+',
29
        ',',
30
        '.',
31
        '[',
32
        ']',
33
        '!',
34
        '"',
35
        '#',
36
        '$',
37
        '%',
38
        '&',
39
        '\'',
40
        '(',
41
        ')',
42
        '*',
43
        '/',
44
        ':',
45
        ';',
46
        '<',
47
        '=',
48
        '>',
49
        '?',
50
        '@',
51
        '\\',
52
        '^',
53
        '`',
54
        '{',
55
        '|',
56
        '}',
57
        '~',
58
    ];
59
60
    /**
61
     * @link http://jsonapi.org/format/#document-member-names-allowed-characters
62
     *
63
     * @var array
64
     */
65
    protected static $forbiddenAsFirstOrLastCharacter = [
66
        '-',
67
        '_',
68
        ' ',
69
    ];
70
71
    /**
72
     * Changes all array keys to under_score format using recursion.
73
     *
74
     * @param array $array
75
     */
76
    protected static function recursiveSetKeysToUnderScore(array &$array)
77
    {
78
        $newArray = [];
79
        foreach ($array as $key => &$value) {
80
            $underscoreKey = RecursiveFormatterHelper::camelCaseToUnderscore($key);
81
            $newArray[$underscoreKey] = $value;
82
83
            if (\is_array($value)) {
84
                self::recursiveSetKeysToUnderScore($newArray[$underscoreKey]);
85
            }
86
        }
87
        $array = $newArray;
88
    }
89
90
    /**
91
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
92
     * @param array                               $array
93
     *
94
     * @return array
95
     */
96
    public static function setResponseDataAttributes(array &$mappings, array &$array)
97
    {
98
        $attributes = [];
99
        $type = $array[Serializer::CLASS_IDENTIFIER_KEY];
100
        $idProperties = RecursiveFormatterHelper::getIdProperties($mappings, $type);
101
102
        foreach ($array as $propertyName => $value) {
103
            if (\in_array($propertyName, $idProperties, true)) {
104
                continue;
105
            }
106
107
            $keyName = self::transformToValidMemberName(RecursiveFormatterHelper::camelCaseToUnderscore($propertyName));
108
109
            if (!empty($value[Serializer::CLASS_IDENTIFIER_KEY]) && empty($mappings[$value[Serializer::CLASS_IDENTIFIER_KEY]])) {
110
                $copy = $value;
111
                self::recursiveSetKeysToUnderScore($copy);
112
                $attributes[$keyName] = $copy;
113
                continue;
114
            }
115
116
            if (self::isScalarValue($value) && empty($mappings[$value[Serializer::SCALAR_TYPE]])) {
117
                $attributes[$keyName] = $value;
118
                continue;
119
            }
120
121
            if (\is_array($value) && !array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $value)) {
122
                if (self::containsClassIdentifierKey($value)) {
123
                    $attributes[$keyName] = $value;
124
                }
125
            }
126
        }
127
128
        return [JsonApiTransformer::ATTRIBUTES_KEY => $attributes];
129
    }
130
131
    /**
132
     * @param string $attributeName
133
     *
134
     * @return string
135
     */
136
    public static function transformToValidMemberName($attributeName)
137
    {
138
        $attributeName = \str_replace(self::$forbiddenMemberNameCharacters, '', $attributeName);
139
140
        $attributeName = \ltrim($attributeName, \implode('', self::$forbiddenAsFirstOrLastCharacter));
141
        $attributeName = \rtrim($attributeName, \implode('', self::$forbiddenAsFirstOrLastCharacter));
142
143
        return $attributeName;
144
    }
145
146
    /**
147
     * @param mixed $value
148
     *
149
     * @return bool
150
     */
151
    protected static function isScalarValue($value)
152
    {
153
        return \is_array($value)
154
        && \array_key_exists(Serializer::SCALAR_TYPE, $value)
155
        && \array_key_exists(Serializer::SCALAR_VALUE, $value);
156
    }
157
158
    /**
159
     * @param array $input
160
     * @param bool  $foundIdentifierKey
161
     *
162
     * @return bool
163
     */
164
    protected static function containsClassIdentifierKey(array $input, $foundIdentifierKey = false)
165
    {
166
        if (!is_array($input)) {
167
            return $foundIdentifierKey || false;
168
        }
169
170
        if (\in_array(Serializer::CLASS_IDENTIFIER_KEY, $input, true)) {
171
            return true;
172
        }
173
174
        if (!empty($input[Serializer::SCALAR_VALUE])) {
175
            $input = $input[Serializer::SCALAR_VALUE];
176
177
            if (\is_array($input)) {
178
                foreach ($input as $value) {
179
                    if (\is_array($value)) {
180
                        $foundIdentifierKey = $foundIdentifierKey
181
                            || self::containsClassIdentifierKey($value, $foundIdentifierKey);
182
                    }
183
                }
184
            }
185
        }
186
187
        return !$foundIdentifierKey;
188
    }
189
}
190