Test Failed
Push — renovate/major-composer-qa-too... ( 6faed2...5f6191 )
by
unknown
11:41
created

PHPArrayToPostgresValueTransformer::formatValue()   C

Complexity

Conditions 12
Paths 16

Size

Total Lines 51
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 12
eloc 29
c 1
b 1
f 0
nc 16
nop 1
dl 0
loc 51
ccs 0
cts 28
cp 0
crap 156
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace MartinGeorgiev\Utils;
6
7
use MartinGeorgiev\Utils\Exception\InvalidArrayFormatException;
8
9
/**
10
 * Handles transformation from PHP values to PostgreSQL values.
11
 *
12
 * @since 3.0
13
 *
14
 * @author Martin Georgiev <[email protected]>
15
 */
16
class PHPArrayToPostgresValueTransformer
17
{
18
    private const POSTGRESQL_EMPTY_ARRAY = '{}';
19
20
    /**
21
     * Transforms a PHP array to a PostgreSQL text array.
22
     * This method supports only single-dimensioned PHP arrays.
23
     * This method relays on the default escaping strategy in PostgreSQL (double quotes).
24
     *
25
     * @throws InvalidArrayFormatException when the input is a multi-dimensional array or has invalid format
26
     */
27
    public static function transformToPostgresTextArray(array $phpArray): string
28
    {
29
        if ($phpArray === []) {
30
            return self::POSTGRESQL_EMPTY_ARRAY;
31
        }
32
33
        if (\array_filter($phpArray, 'is_array')) {
34
            throw InvalidArrayFormatException::multiDimensionalArrayNotSupported();
35
        }
36
37
        /** @var array<int|string, string> */
38
        $processed = \array_map(
39
            static fn (mixed $value): string => self::formatValue($value),
40
            $phpArray
41
        );
42
43
        return '{'.\implode(',', $processed).'}';
44
    }
45
46
    /**
47
     * Formats a single value for PostgreSQL array.
48
     */
49
    private static function formatValue(mixed $value): string
50
    {
51
        if ($value === null) {
52
            return 'NULL';
53
        }
54
55
        if (\is_int($value) || \is_float($value)) {
56
            return (string) $value;
57
        }
58
59
        if (\is_bool($value)) {
60
            return $value ? 'true' : 'false';
61
        }
62
63
        if (\is_object($value)) {
64
            if (\method_exists($value, '__toString')) {
65
                $stringValue = $value->__toString();
66
            } else {
67
                // For objects without __toString, use a default representation
68
                $stringValue = $value::class;
69
            }
70
        } elseif (\is_resource($value)) {
71
            $stringValue = '(resource)';
72
        } else {
73
            $valueType = \get_debug_type($value);
74
75
            if ($valueType === 'string') {
76
                $stringValue = $value;
77
            } elseif (\in_array($valueType, ['int', 'float', 'bool'], true)) {
78
                /** @var bool|float|int $value */
79
                $stringValue = (string) $value;
80
            } else {
81
                $stringValue = $valueType;
82
            }
83
        }
84
85
        \assert(\is_string($stringValue));
86
87
        if ($stringValue === '') {
88
            return '""';
89
        }
90
91
        // Make sure strings are quoted, PostgreSQL will handle this gracefully
92
        // Double the backslashes and escape quotes
93
        $escaped = \str_replace(
94
            ['\\', '"'],
95
            ['\\\\', '\"'],
96
            $stringValue
97
        );
98
99
        return '"'.$escaped.'"';
100
    }
101
}
102