diff --git a/application/Espo/Core/Utils/Json.php b/application/Espo/Core/Utils/Json.php index 4b1c6d213d..ebcabb36e5 100644 --- a/application/Espo/Core/Utils/Json.php +++ b/application/Espo/Core/Utils/Json.php @@ -18,95 +18,101 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ namespace Espo\Core\Utils; class Json { /** - * JSON encode a string - * - * @param string $value - * @param int $options Default 0 - * @param int $depth Default 512 - * @return string - */ + * JSON encode a string + * + * @param string $value + * @param int $options Default 0 + * @param int $depth Default 512 + * @return string + */ public static function encode($value, $options = 0, $depth = 512) { if (version_compare(phpversion(), '5.5.0', '>=')) { - $json = json_encode($value, $options, $depth); - } - elseif (version_compare(phpversion(), '5.3.0', '>=')) { + $json = json_encode($value, $options, $depth); + } + elseif (version_compare(phpversion(), '5.3.0', '>=')) { /*Check if options are supported for this version of PHP*/ - if (is_int($options)) { - $json = json_encode($value, $options); - } + if (is_int($options)) { + $json = json_encode($value, $options); + } else { $json = json_encode($value); } - } - else { - $json = json_encode($value); - } - - if ($json===null) { - $GLOBALS['log']->error('Value cannot be decoded to JSON - '.print_r($value, true)); + } + else { + $json = json_encode($value); } - return $json; + $error = self::getLastError(); + if ($json === null || $error) { + $GLOBALS['log']->error('Json::encode():' . $error . ' - ' . print_r($value, true)); + } + + return $json; } /** - * JSON decode a string (Fixed problem with "\") - * - * @param string $json - * @param bool $assoc Default false - * @param int $depth Default 512 - * @param int $options Default 0 - * @return object - */ + * JSON decode a string (Fixed problem with "\") + * + * @param string $json + * @param bool $assoc Default false + * @param int $depth Default 512 + * @param int $options Default 0 + * @return object + */ public static function decode($json, $assoc = false, $depth = 512, $options = 0) { if (is_array($json)) { - $GLOBALS['log']->warning('JSON:decode() - JSON cannot be decoded - '.$json); + $GLOBALS['log']->warning('Json::decode() - JSON cannot be decoded - '.$json); return false; } - if(version_compare(phpversion(), '5.4.0', '>=')) { - $json = json_decode($json, $assoc, $depth, $options); - } - elseif(version_compare(phpversion(), '5.3.0', '>=')) { - $json = json_decode($json, $assoc, $depth); - } - else { - $json = json_decode($json, $assoc); - } + if(version_compare(phpversion(), '5.4.0', '>=')) { + $json = json_decode($json, $assoc, $depth, $options); + } + elseif(version_compare(phpversion(), '5.3.0', '>=')) { + $json = json_decode($json, $assoc, $depth); + } + else { + $json = json_decode($json, $assoc); + } - return $json; - } + $error = self::getLastError(); + if ($json === null || $error) { + $GLOBALS['log']->error('Json::decode():' . $error); + } - - /** - * Check if the string is JSON - * - * @param string $json - * @return bool - */ - public static function isJSON($json) - { - if ($json === '[]' || $json === '{}') { - return true; - } else if (is_array($json)) { - return false; - } - - return static::decode($json) != null; + return $json; } /** - * Get an array data (if JSON convert to array) + * Check if the string is JSON + * + * @param string $json + * @return bool + */ + public static function isJSON($json) + { + if ($json === '[]' || $json === '{}') { + return true; + } else if (is_array($json)) { + return false; + } + + return static::decode($json) != null; + } + + + /** + * Get an array data (if JSON convert to array) * * @param mixed $data - can be JSON, array * @@ -115,14 +121,64 @@ class Json public static function getArrayData($data) { if (is_array($data)) { - return $data; + return $data; } else if (static::isJSON($data)) { - return static::decode($data, true); - } + return static::decode($data, true); + } return array(); } + + protected static function getLastError($error = null) + { + if (!isset($error)) { + $error = json_last_error(); + } + + switch ($error) { + case JSON_ERROR_NONE: + return false; + break; + + case JSON_ERROR_DEPTH: + return 'The maximum stack depth has been exceeded'; + break; + + case JSON_ERROR_STATE_MISMATCH: + return 'Invalid or malformed JSON'; + break; + + case JSON_ERROR_CTRL_CHAR: + return 'Control character error, possibly incorrectly encoded'; + break; + + case JSON_ERROR_SYNTAX: + return 'Syntax error, malformed JSON'; + break; + + case JSON_ERROR_UTF8: + return 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + + /* Only for PHP 5.5.0 + case JSON_ERROR_RECURSION: + return 'One or more recursive references in the value to be encoded'; + break; + case JSON_ERROR_INF_OR_NAN: + return 'One or more NAN or INF values in the value to be encoded'; + break; + case JSON_ERROR_UNSUPPORTED_TYPE: + return 'A value of a type that cannot be encoded was given'; + break; + */ + + default: + return 'Unknown error'; + break; + } + } + } diff --git a/tests/Espo/Core/Utils/JsonTest.php b/tests/Espo/Core/Utils/JsonTest.php index d15a9c6ed4..19f9a64ee6 100644 --- a/tests/Espo/Core/Utils/JsonTest.php +++ b/tests/Espo/Core/Utils/JsonTest.php @@ -6,38 +6,48 @@ use Espo\Core\Utils\Json; class JsonTest extends \PHPUnit_Framework_TestCase { - function testEncode() + protected function setUp() + { + $GLOBALS['log'] = $this->getMockBuilder('\Espo\Core\Utils\Log')->disableOriginalConstructor()->getMock(); + } + + protected function tearDown() + { + $this->object = NULL; + } + + public function testEncode() { $testVal= array('testOption'=>'Test'); $this->assertEquals(json_encode($testVal), Json::encode($testVal)); } - function testDecode() + public function testDecode() { $testVal= array('testOption'=>'Test'); - $this->assertEquals($testVal, Json::decode(json_encode($testVal), true)); + $this->assertEquals($testVal, Json::decode(json_encode($testVal), true)); $test= '{"folder":"data\/logs"}'; - $this->assertEquals('data/logs', Json::decode($test)->folder); + $this->assertEquals('data/logs', Json::decode($test)->folder); } - function testIsJSON() + public function testIsJSON() { - $this->assertTrue(Json::isJSON('{"database":{"driver":"pdo_mysql","host":"localhost"},"devMode":true}')); - - $this->assertTrue(Json::isJSON('[]')); - - $this->assertTrue(Json::isJSON('{}')); - - $this->assertTrue(Json::isJSON('true')); - + $this->assertTrue(Json::isJSON('{"database":{"driver":"pdo_mysql","host":"localhost"},"devMode":true}')); + + $this->assertTrue(Json::isJSON('[]')); + + $this->assertTrue(Json::isJSON('{}')); + + $this->assertTrue(Json::isJSON('true')); + $this->assertFalse(Json::isJSON('some string')); - + $this->assertTrue(Json::isJSON(true)); $this->assertEquals('true', json_encode(true)); - + $this->assertFalse(Json::isJSON(false)); - $this->assertEquals('false', json_encode(false)); + $this->assertEquals('false', json_encode(false)); }