Skip to content

Commit b7bd302

Browse files
committed
feat: Add PreserveWhitespaceJson cast and middleware for JSON data handling
- Implemented PreserveWhitespaceJson cast to preserve whitespace in JSON attributes. - Created PreserveJsonWhitespace middleware to maintain whitespace in incoming JSON requests. - Updated routes to apply middleware to the pages resource. - Added tests for middleware and cast functionality, ensuring whitespace preservation in various scenarios.
1 parent 29d92e3 commit b7bd302

12 files changed

+1221
-741
lines changed

src/Casts/PreserveWhitespaceJson.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace Coderstm\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class PreserveWhitespaceJson implements CastsAttributes
9+
{
10+
/**
11+
* Cast the given value.
12+
*
13+
* @param \Illuminate\Database\Eloquent\Model $model
14+
* @param string $key
15+
* @param mixed $value
16+
* @param array $attributes
17+
* @return mixed
18+
*/
19+
public function get(Model $model, string $key, mixed $value, array $attributes): mixed
20+
{
21+
if (is_null($value)) {
22+
return null;
23+
}
24+
25+
// If the value is already an array/object, return it as-is
26+
if (is_array($value) || is_object($value)) {
27+
return $value;
28+
}
29+
30+
// Decode JSON with flags that preserve formatting
31+
$decoded = json_decode($value, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
32+
33+
return $decoded;
34+
}
35+
36+
/**
37+
* Prepare the given value for storage.
38+
*
39+
* @param \Illuminate\Database\Eloquent\Model $model
40+
* @param string $key
41+
* @param mixed $value
42+
* @param array $attributes
43+
* @return string|null
44+
*/
45+
public function set(Model $model, string $key, mixed $value, array $attributes): ?string
46+
{
47+
if (is_null($value)) {
48+
return null;
49+
}
50+
51+
// If it's already a JSON string, validate and return it
52+
if (is_string($value)) {
53+
// Test if it's valid JSON
54+
json_decode($value);
55+
if (json_last_error() === JSON_ERROR_NONE) {
56+
return $value;
57+
}
58+
}
59+
60+
// Encode with flags that preserve Unicode and formatting
61+
return json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_UNESCAPED_SLASHES);
62+
}
63+
64+
/**
65+
* Get the serialized representation of the value.
66+
*
67+
* @param \Illuminate\Database\Eloquent\Model $model
68+
* @param string $key
69+
* @param mixed $value
70+
* @param array $attributes
71+
* @return mixed
72+
*/
73+
public function serialize(Model $model, string $key, mixed $value, array $attributes): mixed
74+
{
75+
return $value;
76+
}
77+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Coderstm\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
8+
class PreserveJsonWhitespace
9+
{
10+
/**
11+
* Handle an incoming request.
12+
*
13+
* @param \Illuminate\Http\Request $request
14+
* @param \Closure $next
15+
* @return mixed
16+
*/
17+
public function handle(Request $request, Closure $next)
18+
{
19+
// Only process JSON requests with data field
20+
if ($request->isJson() && $request->has('data')) {
21+
// Get the raw JSON content
22+
$rawContent = $request->getContent();
23+
24+
if (!empty($rawContent)) {
25+
try {
26+
// Decode the raw JSON to preserve whitespace
27+
$rawData = json_decode($rawContent, true, 512, JSON_THROW_ON_ERROR);
28+
29+
if (isset($rawData['data'])) {
30+
// Replace the trimmed data with the original data from raw JSON
31+
$request->merge([
32+
'data' => $rawData['data']
33+
]);
34+
}
35+
} catch (\JsonException $e) {
36+
// If JSON parsing fails, continue with the original request
37+
// This allows Laravel's validation to handle the error
38+
}
39+
}
40+
}
41+
42+
return $next($request);
43+
}
44+
}
Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
<?php //002cd
22
if(extension_loaded('ionCube Loader')){die('The file '.__FILE__." is corrupted.\n");}echo("\nScript error: the ".(($cli=(php_sapi_name()=='cli')) ?'ionCube':'<a href="https://www.ioncube.com">ionCube</a>')." Loader for PHP needs to be installed.\n\nThe ionCube Loader is the industry standard PHP extension for running protected PHP code,\nand can usually be added easily to a PHP installation.\n\nFor Loaders please visit".($cli?":\n\nhttps://get-loader.ioncube.com\n\nFor":' <a href="https://get-loader.ioncube.com">get-loader.ioncube.com</a> and for')." an instructional video please see".($cli?":\n\nhttp://ioncu.be/LV\n\n":' <a href="http://ioncu.be/LV">http://ioncu.be/LV</a> ')."\n\n");exit(199);
33
?>
4-
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
31-
FoLVOA9Y9swn8dVhcYWV284uOwEgePdG1W==
4+
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
31+
vnGsgAjcXpWZSgKzz+jWAAtZaUqu
Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,51 @@
11
<?php //002cd
22
if(extension_loaded('ionCube Loader')){die('The file '.__FILE__." is corrupted.\n");}echo("\nScript error: the ".(($cli=(php_sapi_name()=='cli')) ?'ionCube':'<a href="https://www.ioncube.com">ionCube</a>')." Loader for PHP needs to be installed.\n\nThe ionCube Loader is the industry standard PHP extension for running protected PHP code,\nand can usually be added easily to a PHP installation.\n\nFor Loaders please visit".($cli?":\n\nhttps://get-loader.ioncube.com\n\nFor":' <a href="https://get-loader.ioncube.com">get-loader.ioncube.com</a> and for')." an instructional video please see".($cli?":\n\nhttp://ioncu.be/LV\n\n":' <a href="http://ioncu.be/LV">http://ioncu.be/LV</a> ')."\n\n");exit(199);
33
?>
4-
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
51+
5fKdbFw9SzNNVRcNuJOU

0 commit comments

Comments
 (0)