Skip to content

Commit 58b0928

Browse files
committed
Merge pull request #614 from idio/feature/json-compat
JSON Compat Library
2 parents 181ae4f + ac09e7c commit 58b0928

15 files changed

+118
-32
lines changed

changes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
CHANGES
22

3+
2014-05-13
4+
- Add JSON compat library; Elasticsearch JSON flags and nicer error handling
5+
36
2014-05-12
47
- Update dev builds to phpunit 4.1.*
58

lib/Elastica/Bulk/Action.php

+3-7
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22

33
namespace Elastica\Bulk;
44

5-
if (!defined('JSON_UNESCAPED_UNICODE')) {
6-
define('JSON_UNESCAPED_SLASHES', 64);
7-
define('JSON_UNESCAPED_UNICODE', 256);
8-
}
9-
105
use Elastica\Bulk;
6+
use Elastica\JSON;
117
use Elastica\Index;
128
use Elastica\Type;
139

@@ -185,15 +181,15 @@ public function toArray()
185181
*/
186182
public function toString()
187183
{
188-
$string = json_encode($this->getActionMetadata(), JSON_FORCE_OBJECT) . Bulk::DELIMITER;
184+
$string = JSON::stringify($this->getActionMetadata(), JSON_FORCE_OBJECT) . Bulk::DELIMITER;
189185
if ($this->hasSource()) {
190186
$source = $this->getSource();
191187
if (is_string($source)) {
192188
$string.= $source;
193189
} elseif (is_array($source) && array_key_exists('doc', $source) && is_string($source['doc'])) {
194190
$string.= '{"doc": ' . $source['doc'] . '}';
195191
} else {
196-
$string.= json_encode($source, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
192+
$string.= JSON::stringify($source, 'JSON_ELASTICSEARCH');
197193
}
198194
$string.= Bulk::DELIMITER;
199195
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Elastica\Exception;
4+
5+
/**
6+
* JSON Parse exception
7+
*
8+
* @package Elastica
9+
*/
10+
class JSONParseException extends \RuntimeException implements ExceptionInterface
11+
{
12+
}

lib/Elastica/Exception/PartialShardFailureException.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Elastica\Exception;
44

5+
use Elastica\JSON;
56
use Elastica\Request;
67
use Elastica\Response;
78

@@ -26,7 +27,7 @@ public function __construct(Request $request, Response $response)
2627
parent::__construct($request, $response);
2728

2829
$shardsStatistics = $response->getShardsStatistics();
29-
$this->message = json_encode($shardsStatistics['failed']);
30+
$this->message = JSON::stringify($shardsStatistics['failed']);
3031
}
3132

3233
}

lib/Elastica/JSON.php

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Elastica;
4+
5+
use Elastica\Exception\JSONParseException;
6+
7+
/**
8+
* Elastica JSON tools
9+
*
10+
* @package Elastica
11+
*/
12+
class JSON
13+
{
14+
/**
15+
* Parse JSON string to an array
16+
*
17+
* @param string $json JSON string to parse
18+
* @return array PHP array representation of JSON string
19+
* @link http://php.net/manual/en/function.json-decode.php
20+
* @link http://www.php.net/manual/en/function.json-last-error.php
21+
*/
22+
public static function parse(/* inherit from json_decode */)
23+
{
24+
// extract arguments
25+
$args = func_get_args();
26+
27+
// default to decoding into an assoc array
28+
if (sizeof($args) === 1) {
29+
$args[] = true;
30+
}
31+
32+
// run decode
33+
$array = call_user_func_array('json_decode', $args);
34+
35+
// turn errors into exceptions for easier catching
36+
$error = json_last_error();
37+
if ($error !== JSON_ERROR_NONE) {
38+
throw new JSONParseException($error);
39+
}
40+
41+
// output
42+
return $array;
43+
}
44+
45+
/**
46+
* Convert input to JSON string with standard options
47+
*
48+
* @param mixed check args for PHP function json_encode
49+
* @return string Valid JSON representation of $input
50+
* @link http://php.net/manual/en/function.json-encode.php
51+
*/
52+
public static function stringify(/* inherit from json_encode */)
53+
{
54+
// extract arguments
55+
$args = func_get_args();
56+
57+
// allow special options value for Elasticsearch compatibility
58+
if (sizeof($args) > 1 && $args[1] === 'JSON_ELASTICSEARCH') {
59+
// Use built in JSON constants if available (php >= 5.4)
60+
$args[1] = (defined('JSON_UNESCAPED_SLASHES') ? JSON_UNESCAPED_SLASHES : 64)
61+
| (defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 256);
62+
}
63+
64+
// run encode and output
65+
return call_user_func_array('json_encode', $args);
66+
}
67+
}

lib/Elastica/Log.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Elastica;
44

5+
use Elastica\JSON;
56
use Psr\Log\AbstractLogger;
67

78
/**
@@ -48,7 +49,7 @@ public function __construct($log = '')
4849
public function log($level, $message, array $context = array())
4950
{
5051
$context['error_message'] = $message;
51-
$this->_lastMessage = json_encode($context);
52+
$this->_lastMessage = JSON::stringify($context);
5253

5354
if (!empty($this->_log) && is_string($this->_log)) {
5455
error_log($this->_lastMessage . PHP_EOL, 3, $this->_log);

lib/Elastica/Multi/Search.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Elastica\Multi;
44

55
use Elastica\Client;
6+
use Elastica\JSON;
67
use Elastica\Request;
78
use Elastica\Search as BaseSearch;
89

@@ -170,8 +171,8 @@ protected function _getSearchData(BaseSearch $search)
170171
$header = (empty($header)) ? new \stdClass : $header;
171172
$query = $search->getQuery();
172173

173-
$data = json_encode($header) . "\n";
174-
$data.= json_encode($query->toArray()) . "\n";
174+
$data = JSON::stringify($header) . "\n";
175+
$data.= JSON::stringify($query->toArray()) . "\n";
175176

176177
return $data;
177178
}

lib/Elastica/Query/Builder.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<?php
22

33
namespace Elastica\Query;
4+
45
use Elastica\Exception\InvalidException;
6+
use Elastica\Exception\JSONParseException;
7+
use Elastica\JSON;
58

69
/**
710
* Query Builder.
@@ -59,13 +62,11 @@ public function __toString()
5962
*/
6063
public function toArray()
6164
{
62-
$array = json_decode($this->__toString(), true);
63-
64-
if (is_null($array)) {
65+
try {
66+
return JSON::parse($this->__toString());
67+
} catch (JSONParseException $e) {
6568
throw new InvalidException('The query produced is invalid');
6669
}
67-
68-
return $array;
6970
}
7071

7172
/**

lib/Elastica/Request.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<?php
22

33
namespace Elastica;
4+
45
use Elastica\Exception\InvalidException;
6+
use Elastica\JSON;
57

68
/**
79
* Elastica Request object
@@ -185,7 +187,7 @@ public function toArray()
185187
*/
186188
public function toString()
187189
{
188-
return json_encode($this->toArray());
190+
return JSON::stringify($this->toArray());
189191
}
190192

191193
/**

lib/Elastica/Response.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Elastica;
44

5+
use Elastica\Exception\JSONParseException;
56
use Elastica\Exception\NotFoundException;
7+
use Elastica\JSON;
68

79
/**
810
* Elastica Response object
@@ -177,11 +179,10 @@ public function getData()
177179
if ($response === false) {
178180
$this->_error = true;
179181
} else {
180-
181-
$tempResponse = json_decode($response, true);
182-
// Check if decoding went as expected. If error is returned, json_decode makes empty string of string
183-
if (json_last_error() == JSON_ERROR_NONE) {
184-
$response = $tempResponse;
182+
try {
183+
$response = JSON::parse($response);
184+
} catch (JSONParseException $e) {
185+
// leave reponse as is if parse fails
185186
}
186187
}
187188

lib/Elastica/Transport/Http.php

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22

33
namespace Elastica\Transport;
44

5-
if (!defined('JSON_UNESCAPED_UNICODE')) {
6-
define('JSON_UNESCAPED_SLASHES', 64);
7-
define('JSON_UNESCAPED_UNICODE', 256);
8-
}
9-
105
use Elastica\Exception\Connection\HttpException;
116
use Elastica\Exception\PartialShardFailureException;
127
use Elastica\Exception\ResponseException;
8+
use Elastica\JSON;
139
use Elastica\Request;
1410
use Elastica\Response;
1511

@@ -103,7 +99,7 @@ public function exec(Request $request, array $params)
10399
}
104100

105101
if (is_array($data)) {
106-
$content = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
102+
$content = JSON::stringify($data, 'JSON_ELASTICSEARCH');
107103
} else {
108104
$content = $data;
109105
}

lib/Elastica/Transport/Memcache.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Elastica\Exception\InvalidException;
66
use Elastica\Exception\PartialShardFailureException;
77
use Elastica\Exception\ResponseException;
8+
use Elastica\JSON;
89
use Elastica\Request;
910
use Elastica\Response;
1011

@@ -40,7 +41,7 @@ public function exec(Request $request, array $params)
4041

4142
if (!empty($data)) {
4243
if (is_array($data)) {
43-
$content = json_encode($data);
44+
$content = JSON::stringify($data);
4445
} else {
4546
$content = $data;
4647
}

lib/Elastica/Transport/Null.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Elastica\Transport;
44

5+
use Elastica\JSON;
56
use Elastica\Request;
67
use Elastica\Response;
78

@@ -38,6 +39,6 @@ public function exec(Request $request, array $params)
3839
"params" => $params
3940
);
4041

41-
return new Response(json_encode($response));
42+
return new Response(JSON::stringify($response));
4243
}
4344
}

lib/Elastica/Transport/Thrift.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Elastica\Exception\PartialShardFailureException;
77
use Elastica\Exception\ResponseException;
88
use Elastica\Exception\RuntimeException;
9+
use Elastica\JSON;
910
use Elastica\Request;
1011
use Elastica\Response;
1112
use Elastica\Connection;
@@ -136,7 +137,7 @@ public function exec(Request $request, array $params)
136137
$data = $request->getData();
137138
if (!empty($data)) {
138139
if (is_array($data)) {
139-
$content = json_encode($data);
140+
$content = JSON::stringify($data);
140141
} else {
141142
$content = $data;
142143
}

lib/Elastica/Util.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Elastica;
44

5+
use Elastica\JSON;
6+
57
/**
68
* Elastica tools
79
*
@@ -162,7 +164,7 @@ public static function convertRequestToCurlCommand(Request $request)
162164

163165
$data = $request->getData();
164166
if (!empty($data)) {
165-
$message .= ' -d \'' . json_encode($data) . '\'';
167+
$message .= ' -d \'' . JSON::stringify($data) . '\'';
166168
}
167169
return $message;
168170
}

0 commit comments

Comments
 (0)