Completed
Push — master ( 584c55...9d713d )
by Andreas
08:16
created

TypeConverter   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 87.88%

Importance

Changes 0
Metric Value
dl 0
loc 154
ccs 58
cts 66
cp 0.8788
rs 10
c 0
b 0
f 0
wmc 30
lcom 1
cbo 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
B fromLegacy() 0 18 5
B toLegacy() 0 18 5
A convertProjection() 0 9 4
A isNumericArray() 0 4 2
C convertBSONObjectToLegacy() 0 29 11
A ensureCorrectType() 0 8 3
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 */
15
16
namespace Alcaeus\MongoDbAdapter;
17
18
use MongoDB\BSON;
19
use MongoDB\Model;
20
21
/**
22
 * @internal
23
 */
24
class TypeConverter
25
{
26
    /**
27
     * Converts a legacy type to the new BSON type
28
     *
29
     * This method handles type conversion from ext-mongo to ext-mongodb:
30
     *  - For all types (MongoId, MongoDate, etc.) it returns the correct BSON
31
     *    object instance
32
     *  - For arrays and objects it iterates over properties and converts each
33
     *    item individually
34
     *  - For other types it returns the value unconverted
35
     *
36
     * @param mixed $value
37
     * @return mixed
38
     */
39 153
    public static function fromLegacy($value)
40
    {
41 153
        switch (true) {
42 153
            case $value instanceof TypeInterface:
43 117
                return $value->toBSONType();
44 152
            case is_array($value):
45 152
            case is_object($value);
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
46 152
                $result = [];
47
48 152
                foreach ($value as $key => $item) {
49 149
                    $result[$key] = self::fromLegacy($item);
50 152
                }
51
52 152
                return self::ensureCorrectType($result, is_object($value));
53 143
            default:
54 143
                return $value;
55 143
        }
56
    }
57
58
    /**
59
     * Converts a BSON type to the legacy types
60
     *
61
     * This method handles type conversion from ext-mongodb to ext-mongo:
62
     *  - For all instances of BSON\Type it returns an object of the
63
     *    corresponding legacy type (MongoId, MongoDate, etc.)
64
     *  - For arrays and objects it iterates over properties and converts each
65
     *    item individually
66
     *  - For other types it returns the value unconverted
67
     *
68
     * @param mixed $value
69
     * @return mixed
70
     */
71 63
    public static function toLegacy($value)
72
    {
73 63
        switch (true) {
74 63
            case $value instanceof BSON\Type:
75 56
                return self::convertBSONObjectToLegacy($value);
76 55
            case is_array($value):
77 55
            case is_object($value):
78 5
                $result = [];
79
80 5
                foreach ($value as $key => $item) {
81 5
                    $result[$key] = self::toLegacy($item);
82 5
                }
83
84 5
                return $result;
85 54
            default:
86 54
                return $value;
87 54
        }
88
    }
89
90
    /**
91
     * Converts a projection used in find queries.
92
     *
93
     * This method handles conversion from the legacy syntax (e.g. ['x', 'y', 'z'])
94
     * to the new syntax (e.g. ['x' => true, 'y' => true, 'z' => true]). While
95
     * this was never documented, the legacy driver applied the same conversion.
96
     *
97
     * @param array $fields
98
     * @return array
99
     */
100 51
    public static function convertProjection($fields)
101
    {
102 51
        if (! is_array($fields) || $fields === []) {
103 23
            return [];
104
        }
105
106 33
        $projection = TypeConverter::isNumericArray($fields) ? array_fill_keys($fields, true) : $fields;
107 33
        return TypeConverter::fromLegacy($projection);
108
    }
109
110
    /**
111
     * Helper method to find out if an array has numerical indexes
112
     *
113
     * For performance reason, this method checks the first array index only.
114
     * More thorough inspection of the array might be needed.
115
     * Note: Returns true for empty arrays to preserve compatibility with empty
116
     * lists.
117
     *
118
     * @param array $array
119
     * @return bool
120
     */
121 151
    public static function isNumericArray(array $array)
122
    {
123 151
        return $array === [] || is_numeric(array_keys($array)[0]);
124
    }
125
126
    /**
127
     * Converter method to convert a BSON object to its legacy type
128
     *
129
     * @param BSON\Type $value
130
     * @return mixed
131
     */
132 56
    private static function convertBSONObjectToLegacy(BSON\Type $value)
133
    {
134 56
        switch (true) {
135 56
            case $value instanceof BSON\ObjectID:
136 36
                return new \MongoId($value);
137 50
            case $value instanceof BSON\Binary:
138 6
                return new \MongoBinData($value);
139 50
            case $value instanceof BSON\Javascript:
140
                return new \MongoCode($value);
141 50
            case $value instanceof BSON\MaxKey:
142
                return new \MongoMaxKey();
143 50
            case $value instanceof BSON\MinKey:
144
                return new \MongoMinKey();
145 50
            case $value instanceof BSON\Regex:
146
                return new \MongoRegex($value);
147 50
            case $value instanceof BSON\Timestamp:
148
                return new \MongoTimestamp($value);
149 50
            case $value instanceof BSON\UTCDatetime:
150 8
                return new \MongoDate($value);
151 50
            case $value instanceof Model\BSONDocument:
152 50
            case $value instanceof Model\BSONArray:
153 50
                return array_map(
154 50
                    ['self', 'toLegacy'],
155 50
                    $value->getArrayCopy()
156 50
                );
157
            default:
158
                return $value;
159
        }
160
    }
161
162
    /**
163
     * Converts all arrays with non-numeric keys to stdClass
164
     *
165
     * @param array $array
166
     * @param bool $wasObject
167
     * @return array|Model\BSONArray|Model\BSONDocument
168
     */
169 152
    private static function ensureCorrectType(array $array, $wasObject = false)
170
    {
171 152
        if ($wasObject || ! static::isNumericArray($array)) {
172 146
            return new Model\BSONDocument($array);
173
        }
174
175 40
        return $array;
176
    }
177
}
178