Completed
Push — master ( 07ea1d...d01bfd )
by Delete
04:05 queued 02:01
created

Encoder::encode()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 4
eloc 10
c 5
b 0
f 0
nc 4
nop 3
dl 0
loc 21
rs 9.0534
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
        // Try to encode the data
83
        // @codeCoverageIgnoreStart
84
        if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
85
            $json = $this->encodePhpGte55($value, $options, $depth);
86
        } else {
87
            $json = $this->encodePhpLt55($value, $options);
88
        }
89
        // @codeCoverageIgnoreEnd
90
91
        // Convert
92
        return $this->convertEncoding($json, self::UTF8, $this->getEncoding());
93
    }
94
95
    /**
96
     * @param mixed $value
97
     * @param int $options
98
     * @param int $depth
99
     *
100
     * @return string
101
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
102
     */
103
    private function encodePhpGte55($value, $options, $depth)
104
    {
105
        $json = \json_encode($value, $options, $depth);
106
107
        if (!is_string($json)) {
108
            throw $this->getNativeJsonErrorException();
109
        }
110
111
        return $json;
112
    }
113
114
    /**
115
     * @param mixed $value
116
     * @param int $options
117
     *
118
     * @return string
119
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
120
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
121
     */
122
    private function encodePhpLt55($value, $options)
123
    {
124
        // Although the json_last_error() function exists, json_encode() in PHP < 5.5.0 sometimes
125
        // triggers an error, for example when an unsupported type is tried to be encoded. We
126
        // suppress these errors and throw an own exception instead.
127
        $json = @\json_encode($value, $options);
128
        if ($value !== null && $json === 'null') {
129
            throw new InvalidArgumentException('The type tried to encode is not supported.', 1478445896);
130
        }
131
132
        if (!is_string($json)) {
133
            throw $this->getNativeJsonErrorException();
134
        }
135
136
        return $json;
137
    }
138
}
139