Completed
Push — master ( 2af44c...3f0e2b )
by Delete
02:17
created

Converter::getNativeJsonErrorException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Crossjoin\Json;
3
4
use Crossjoin\Json\Exception\ConversionFailedException;
5
use Crossjoin\Json\Exception\ExtensionRequiredException;
6
use Crossjoin\Json\Exception\InvalidArgumentException;
7
use Crossjoin\Json\Exception\NativeJsonErrorException;
8
9
/**
10
 * Class Converter
11
 *
12
 * @package Crossjoin\Json
13
 * @author Christoph Ziegenberg <[email protected]>
14
 */
15
abstract class Converter
16
{
17
    const UTF8    = 'UTF-8';
18
    const UTF16BE = 'UTF-16BE';
19
    const UTF16LE = 'UTF-16LE';
20
    const UTF32BE = 'UTF-32BE';
21
    const UTF32LE = 'UTF-32LE';
22
23
    /**
24
     * @param string $string
25
     * @param string $fromEncoding
26
     * @param string $toEncoding
27
     *
28
     * @return string
29
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
30
     * @throws \Crossjoin\Json\Exception\ConversionFailedException
31
     * @throws \Crossjoin\Json\Exception\ExtensionRequiredException
32
     */
33
    public function convertEncoding($string, $fromEncoding, $toEncoding)
34
    {
35
        // Check arguments
36
        if (!is_string($string)) {
37
            throw new InvalidArgumentException(
38
                sprintf("String expected for argument '%s'. Got '%s'.", 'json', gettype($string)),
39
                1478195990
40
            );
41
        }
42
        if (!is_string($fromEncoding)) {
43
            throw new InvalidArgumentException(
44
                sprintf("String expected for argument '%s'. Got '%s'.", 'fromEncoding', gettype($fromEncoding)),
45
                1478195991
46
            );
47
        }
48
        if (!is_string($toEncoding)) {
49
            throw new InvalidArgumentException(
50
                sprintf("String expected for argument '%s'. Got '%s'.", 'toEncoding', gettype($toEncoding)),
51
                1478195992
52
            );
53
        }
54
55
        // Try different conversion functions, ordered by speed
56
        // @codeCoverageIgnoreStart
57
        if (function_exists('iconv')) {
58
            $string = iconv($fromEncoding, $toEncoding . '//IGNORE', $string);
59
            if ($string === false) {
60
                throw new ConversionFailedException('Error while converting the encoding.', 1478193725);
61
            }
62
        } elseif (class_exists('\\UConverter')) {
63
            /** @noinspection PhpUndefinedClassInspection */
64
            $uConverter = new \UConverter($toEncoding, $fromEncoding);
65
            /** @noinspection PhpUndefinedMethodInspection */
66
            $string = $uConverter->convert($string);
67
        } elseif (function_exists('mb_convert_encoding')) {
68
            $string = mb_convert_encoding($string, $toEncoding, $fromEncoding);
69
        } else {
70
            throw new ExtensionRequiredException(
71
                "The 'iconv', 'intl' or the 'Multibyte String' extension is required to convert the JSON encoding.",
72
                1478095252
73
            );
74
        }
75
        // @codeCoverageIgnoreEnd
76
77
        return $string;
78
    }
79
80
    /**
81
     * Removes the byte order mark (BOM) from the JSON text. This is not allowed in JSON,
82
     * but may be ignored when parsing it.
83
     *
84
     * @param string $string
85
     *
86
     * @return string
87
     * @throws \Crossjoin\Json\Exception\InvalidArgumentException
88
     */
89
    public function removeByteOrderMark($string)
90
    {
91
        // Check arguments
92 View Code Duplication
        if (!is_string($string)) {
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...
93
            throw new InvalidArgumentException(
94
                sprintf("String expected for argument '%s'. Got '%s'.", 'string', gettype($string)),
95
                1478195910
96
            );
97
        }
98
99
        return (string)preg_replace(
100
            '/^(?:' .
101
            '\xEF\xBB\xBF|' .     // UTF-8 BOM
102
            '\x00\x00\xFE\xFF|' . // UTF-32BE BOM
103
            '\xFF\xFE\x00\x00|' . // UTF-32LE BOM (before UTF-16LE check!)
104
            '\xFE\xFF|' .         // UTF-16BE BOM
105
            '\xFF\xFE' .          // UTF-16LE BOM
106
            ')/',
107
            '',
108
            $string
109
        );
110
    }
111
112
    /**
113
     * @return NativeJsonErrorException
114
     */
115
    protected function getNativeJsonErrorException()
116
    {
117
        if (function_exists('\json_last_error_msg')) {
118
            return new NativeJsonErrorException(\json_last_error_msg(), \json_last_error());
119
        } else {
120
            return new NativeJsonErrorException('An error occurred while encoding/decoding JSON.', \json_last_error());
121
        }
122
    }
123
}
124