Completed
Branch master (07ea1d)
by Delete
04:09 queued 02:10
created

Encoder::encodePhpGte55()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 3
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
        if (is_string($encoding)) {
52
            if (in_array($encoding, array(self::UTF8, self::UTF16BE, self::UTF16LE, self::UTF32BE, self::UTF32LE), true)) {
53
                $this->encoding = $encoding;
54
            } else {
55
                throw new EncodingNotSupportedException(sprintf("Unsupported encoding '%s'.", $encoding), 1478101930);
56
            }
57
        } else {
58
            throw InvalidArgumentException::getInstance('string', 'encoding', $encoding, 1478196374);
59
        }
60
    }
61
62
    /**
63
     * @param mixed $value
64
     * @param int $options
65
     * @param int $depth
66
     *
67
     * @return string
68
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
69
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
70
     * @throws \Crossjoin\Json\Exception\ExtensionRequiredException
71
     * @throws \Crossjoin\Json\Exception\ConversionFailedException
72
     */
73
    public function encode($value, $options = 0, $depth = 512)
74
    {
75
        // Check arguments
76
        if (!is_int($options)) {
77
            throw InvalidArgumentException::getInstance('integer', 'options', $options, 1478418109);
78
        } elseif (!is_int($depth)) {
79
            throw InvalidArgumentException::getInstance('integer', 'depth', $depth, 1478418110);
80
        }
81
82
        $toEncoding = $this->getEncoding();
83
84
        // Try to encode the data
85
        // @codeCoverageIgnoreStart
86
        if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
87
            $json = $this->encodePhpGte55($value, $options, $depth);
88
        } else {
89
            $json = $this->encodePhpLt55($value, $options);
90
        }
91
        // @codeCoverageIgnoreEnd
92
93
        // Convert
94
        if ($toEncoding !== self::UTF8) {
95
            $json = $this->convertEncoding($json, self::UTF8, $toEncoding);
96
        }
97
98
        return $json;
99
    }
100
101
    /**
102
     * @param mixed $value
103
     * @param int $options
104
     * @param int $depth
105
     *
106
     * @return string
107
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
108
     */
109
    private function encodePhpGte55($value, $options, $depth)
110
    {
111
        $json = \json_encode($value, $options, $depth);
112
113
        if (!is_string($json)) {
114
            throw $this->getNativeJsonErrorException();
115
        }
116
117
        return $json;
118
    }
119
120
    /**
121
     * @param mixed $value
122
     * @param int $options
123
     *
124
     * @return string
125
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
126
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
127
     */
128
    private function encodePhpLt55($value, $options)
129
    {
130
        // Although the json_last_error() function exists, json_encode() in PHP < 5.5.0 sometimes
131
        // triggers an error, for example when an unsupported type is tried to be encoded. We
132
        // suppress these errors and throw an own exception instead.
133
        $json = @\json_encode($value, $options);
134
        if ($value !== null && $json === 'null') {
135
            throw new InvalidArgumentException('The type tried to encode is not supported.', 1478445896);
136
        }
137
138
        if (!is_string($json)) {
139
            throw $this->getNativeJsonErrorException();
140
        }
141
142
        return $json;
143
    }
144
}
145