Encoder::setEncoding()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 9.4285
1
<?php
2
namespace Crossjoin\Json;
3
4
use Crossjoin\Json\Exception\EncodingNotSupportedException;
5
use Crossjoin\Json\Exception\InvalidArgumentException;
6
7
/**
8
 * Class Encoder
9
 *
10
 * @package Crossjoin\Json
11
 * @author Christoph Ziegenberg <[email protected]>
12
 */
13
class Encoder extends Converter
14
{
15
    const UTF16 = self::UTF16BE;
16
    const UTF32 = self::UTF32BE;
17
18
    /**
19
     * @var string
20
     */
21
    private $encoding = self::UTF8;
22
23
    /**
24
     * Encoder constructor.
25
     *
26
     * @param string $encoding
27
     * @throws \Crossjoin\Json\Exception\EncodingNotSupportedException
28
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
29
     */
30
    public function __construct($encoding = self::UTF8)
31
    {
32
        $this->setEncoding($encoding);
33
    }
34
35
    /**
36
     * @return string
37
     */
38
    public function getEncoding()
39
    {
40
        return $this->encoding;
41
    }
42
43
    /**
44
     * @param string $encoding
45
     *
46
     * @throws \Crossjoin\Json\Exception\EncodingNotSupportedException
47
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
48
     */
49
    public function setEncoding($encoding)
50
    {
51
        InvalidArgumentException::validateArgument(InvalidArgumentException::TYPE_STRING, 'encoding', $encoding, 1478196374);
52
53
        if (in_array($encoding, array(self::UTF8, self::UTF16BE, self::UTF16LE, self::UTF32BE, self::UTF32LE), true)) {
54
            $this->encoding = $encoding;
55
        } else {
56
            throw new EncodingNotSupportedException(sprintf("Unsupported encoding '%s'.", $encoding), 1478101930);
57
        }
58
    }
59
60
    /**
61
     * @param mixed $value
62
     * @param int $options
63
     * @param int $depth
64
     *
65
     * @return string
66
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
67
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
68
     * @throws \Crossjoin\Json\Exception\ExtensionRequiredException
69
     * @throws \Crossjoin\Json\Exception\ConversionFailedException
70
     */
71
    public function encode($value, $options = 0, $depth = 512)
72
    {
73
        // Check arguments
74
        InvalidArgumentException::validateArgument(InvalidArgumentException::TYPE_INTEGER, 'options', $options, 1478418109);
75
        InvalidArgumentException::validateArgument(InvalidArgumentException::TYPE_INTEGER, 'depth', $depth, 1478418110);
76
77
        // Try to encode the data
78
        // @codeCoverageIgnoreStart
79
        if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
80
            $json = $this->encodePhpGte55($value, $options, $depth);
81
        } else {
82
            $json = $this->encodePhpLt55($value, $options);
83
        }
84
        // @codeCoverageIgnoreEnd
85
86
        // Convert
87
        return $this->convertEncoding($json, self::UTF8, $this->getEncoding());
88
    }
89
90
    /**
91
     * @param mixed $value
92
     * @param int $options
93
     * @param int $depth
94
     *
95
     * @return string
96
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
97
     */
98
    private function encodePhpGte55($value, $options, $depth)
99
    {
100
        // @codeCoverageIgnoreStart
101
        $json = \json_encode($value, $options, $depth);
102
103
        if (!is_string($json)) {
104
            throw $this->getNativeJsonErrorException();
105
        }
106
107
        return $json;
108
        // @codeCoverageIgnoreEnd
109
    }
110
111
    /**
112
     * @param mixed $value
113
     * @param int $options
114
     *
115
     * @return string
116
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
117
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
118
     */
119
    private function encodePhpLt55($value, $options)
120
    {
121
        // Although the json_last_error() function exists, json_encode() in PHP < 5.5.0 sometimes
122
        // triggers an error, for example when an unsupported type is tried to be encoded. We
123
        // suppress these errors and throw an own exception instead.
124
125
        // @codeCoverageIgnoreStart
126
        $json = @\json_encode($value, $options);
127
        if ($value !== null && $json === 'null') {
128
            throw new InvalidArgumentException('The type tried to encode is not supported.', 1478445896);
129
        }
130
131
        if (!is_string($json)) {
132
            throw $this->getNativeJsonErrorException();
133
        }
134
135
        return $json;
136
        // @codeCoverageIgnoreEnd
137
    }
138
}
139