Completed
Push — master ( 9e2bf7...657356 )
by Delete
02:14
created

Encoder::encode()   C

Complexity

Conditions 9
Paths 11

Size

Total Lines 48
Code Lines 24

Duplication

Lines 19
Ratio 39.58 %

Importance

Changes 0
Metric Value
cc 9
eloc 24
nc 11
nop 3
dl 19
loc 48
rs 5.5102
c 0
b 0
f 0
1
<?php
2
namespace Crossjoin\Json;
3
4
use Crossjoin\Json\Exception\ConversionFailedException;
5
use Crossjoin\Json\Exception\EncodingNotSupportedException;
6
use Crossjoin\Json\Exception\InvalidArgumentException;
7
use Crossjoin\Json\Exception\NativeJsonErrorException;
8
9
/**
10
 * Class Encoder
11
 *
12
 * @package Crossjoin\Json
13
 * @author Christoph Ziegenberg <[email protected]>
14
 */
15
class Encoder extends Converter
16
{
17
    const UTF16 = self::UTF16BE;
18
    const UTF32 = self::UTF32BE;
19
20
    /**
21
     * @var string
22
     */
23
    private $encoding = self::UTF8;
24
25
    /**
26
     * Encoder constructor.
27
     *
28
     * @param string $encoding
29
     * @throws \Crossjoin\Json\Exception\EncodingNotSupportedException
30
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
31
     */
32
    public function __construct($encoding = self::UTF8)
33
    {
34
        $this->setEncoding($encoding);
35
    }
36
37
    /**
38
     * @return string
39
     */
40
    public function getEncoding()
41
    {
42
        return $this->encoding;
43
    }
44
45
    /**
46
     * @param string $encoding
47
     *
48
     * @throws \Crossjoin\Json\Exception\EncodingNotSupportedException
49
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
50
     */
51
    public function setEncoding($encoding)
52
    {
53
        if (is_string($encoding)) {
54
            if (in_array($encoding, array(self::UTF8, self::UTF16BE, self::UTF16LE, self::UTF32BE, self::UTF32LE), true)) {
55
                $this->encoding = $encoding;
56
            } else {
57
                throw new EncodingNotSupportedException(sprintf("Unsupported encoding '%s'.", $encoding), 1478101930);
58
            }
59
        } else {
60
            throw new InvalidArgumentException(
61
                sprintf("String expected for argument '%s'. Got '%s'.", 'encoding', gettype($encoding)),
62
                1478196374
63
            );
64
        }
65
    }
66
67
    /**
68
     * @param mixed $value
69
     * @param int $options
70
     * @param int $depth
71
     *
72
     * @return string
73
     * @throws \Crossjoin\Json\Exception\NativeJsonErrorException
74
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
75
     * @throws \Crossjoin\Json\Exception\ExtensionRequiredException
76
     * @throws \Crossjoin\Json\Exception\ConversionFailedException
77
     */
78
    public function encode($value, $options = 0, $depth = 512)
79
    {
80
        // Check arguments
81 View Code Duplication
        if (!is_int($options)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
            throw new InvalidArgumentException(
83
                sprintf("Integer expected for argument '%s'. Got '%s'.", 'options', gettype($options)),
84
                1478418109
85
            );
86
        }
87 View Code Duplication
        if (!is_int($depth)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
            throw new InvalidArgumentException(
89
                sprintf("Integer expected for argument '%s'. Got '%s'.", 'depth', gettype($depth)),
90
                1478418110
91
            );
92
        }
93
94
        $toEncoding = $this->getEncoding();
95
96
        // Try to encode the data
97
        // @codeCoverageIgnoreStart
98
        if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
99
            $json = \json_encode($value, $options, $depth);
100
        } else {
101
            // Although the json_last_error() function exists, json_encode() in PHP < 5.5.0 sometimes
102
            // triggers an error, for example when an unsupported type is tried to be encoded. We
103
            // suppress these errors and throw an own exception instead.
104
            $json = @\json_encode($value, $options);
105
            if ($value !== null && $json === 'null') {
106
                throw new InvalidArgumentException('The type tried to encode is not supported.', 1478445896);
107
            }
108
        }
109
        // @codeCoverageIgnoreEnd
110
111 View Code Duplication
        if ($json === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
            if (function_exists('\json_last_error_msg')) {
113
                throw new NativeJsonErrorException(\json_last_error_msg(), \json_last_error());
114
            } else {
115
                throw new NativeJsonErrorException('An error occurred while encoding JSON.', \json_last_error());
116
            }
117
        }
118
119
        // Convert
120
        if ($toEncoding !== self::UTF8) {
121
            $json = $this->convertEncoding($json, self::UTF8, $toEncoding);
122
        }
123
124
        return $json;
125
    }
126
}
127