Skip to content

Commit af130a2

Browse files
committed
Initial
0 parents  commit af130a2

15 files changed

+419
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.idea
2+
/modules
3+
.fuse_*

README.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# JSONPlus `1.0`
2+
3+
## Getting started
4+
5+
```php
6+
<?php
7+
8+
use de\interaapps\jsonplus\attributes\Serialize;
9+
use de\interaapps\jsonplus\JSONModel;use de\interaapps\jsonplus\JSONPlus;
10+
11+
class Test2 {
12+
use JSONModel;
13+
14+
#[Serialize("my_array")]
15+
public array $myArray;
16+
}
17+
18+
class Test {
19+
// Adds the Test#toJson and Test::fromJson functions
20+
use JSONModel;
21+
22+
public string $test;
23+
public Test2 $test2;
24+
}
25+
26+
$test = Test::fromJson('{
27+
"test": "Hello World",
28+
"test2": {
29+
"my_array": ["Hello There"]
30+
}
31+
}');
32+
33+
echo $test->toJson();
34+
35+
// Custom JSONPlus Instance
36+
$jsonPlus = JSONPlus::createDefault();
37+
// $jsonPlus = new JSONPlus(new PHPJsonSerializationAdapter());
38+
$arrJson = $jsonPlus->toJson([
39+
"A", "B", "C"
40+
]);
41+
echo $arrJson;
42+
// '["A", "B", "C"]'
43+
44+
echo $jsonPlus->fromJson($arrJson)[0];
45+
// "A"
46+
47+
// Setting JSONModal
48+
Test::setJsonPlusInstance($jsonPlus);
49+
// For all (Default instance)
50+
JSONPlus::$default = $jsonPlus;
51+
```
52+
53+
## Installation
54+
#### UPPM
55+
```
56+
uppm install interaapps/jsonplus
57+
```
58+
#### Composer
59+
```
60+
composer require interaapps/jsonplus
61+
```

autoload.php

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
return function ($dir = ".", $mod = "main") {
3+
$uppmlock = (object) [];
4+
if (file_exists("uppm.locks.json")) {
5+
$uppmlock = json_decode(file_get_contents($dir . "/" . "uppm.locks.json"));
6+
if (isset($uppmlock->namespace_bindings))
7+
$uppmlock->namespaceBindings = $uppmlock->namespace_bindings;
8+
if (isset($uppmlock->directnamespaces))
9+
$uppmlock->directNamespaceBindings = $uppmlock->directnamespaces;
10+
}
11+
12+
spl_autoload_register(function($class) use ($dir, $mod, $uppmlock) {
13+
if (isset($uppmlock->directNamespaceBindings->{$class}))
14+
@include_once "$dir/".str_replace("\\","/",$uppmlock->directNamespaceBindings->{$class});
15+
else if(file_exists("$dir/".str_replace("\\","/",$class).".php"))
16+
@include_once "$dir/".str_replace("\\","/",$class).".php";
17+
else if(file_exists("$dir/modules/".str_replace("\\","/",$class).".php"))
18+
@include_once "$dir/modules/".str_replace("\\","/",$class).".php";
19+
else if(file_exists("$dir/src/".str_replace("\\","/",$class).".php"))
20+
@include_once "$dir/src/".str_replace("\\","/",$class).".php";
21+
else if(file_exists("$dir/src/$mod/".str_replace("\\","/",$class).".php"))
22+
@include_once "$dir/src/$mod/".str_replace("\\","/",$class).".php";
23+
else if(isset($uppmlock->namespaceBindings)) {
24+
foreach ($uppmlock->namespaceBindings as $namespaceBinding => $folder){
25+
if (substr($class, 0, strlen($namespaceBinding)) === $namespaceBinding) {
26+
$splitClass = explode($namespaceBinding."\\", $class, 2);
27+
if (isset($splitClass[1]) && $splitClass[1] != "")
28+
$class = $splitClass[1];
29+
$classFile = $folder.'/'.str_replace("\\","/", $class).".php";
30+
if (file_exists($dir."/".$classFile)) {
31+
@include_once $dir."/".$classFile;
32+
break;
33+
}
34+
}
35+
}
36+
}
37+
});
38+
39+
if (isset($uppmlock->initscripts))
40+
foreach ($uppmlock->initscripts as $script) {
41+
@include_once $script;
42+
}
43+
44+
};

composer.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "interaapps/module",
3+
"version": "1.0.0",
4+
"type": "library",
5+
"authors": [
6+
{
7+
"name": "JulianFun123",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {
12+
"php": ">=8.0"
13+
},
14+
"autoload": {
15+
"psr-4": {
16+
"de\\interaapps\\ulole\\jsonplus\\": "src/main/de/interaapps/jsonplus"
17+
}
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
namespace de\interaapps\jsonplus;
3+
4+
trait JSONModel {
5+
private static JSONPlus $jsonPlusInstance;
6+
7+
public static function fromJson($json) : self {
8+
if (!isset(self::$jsonPlusInstance)) self::$jsonPlusInstance = JSONPlus::$default;
9+
return self::$jsonPlusInstance->fromJson($json, self::class);
10+
}
11+
12+
public function toJson() : string {
13+
if (!isset(self::$jsonPlusInstance)) self::$jsonPlusInstance = JSONPlus::$default;
14+
return self::$jsonPlusInstance->toJson($this, self::class);
15+
}
16+
17+
public static function setJsonPlusInstance(JSONPlus $jsonPlusInstance): void {
18+
self::$jsonPlusInstance = $jsonPlusInstance;
19+
}
20+
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
namespace de\interaapps\jsonplus;
3+
4+
use de\interaapps\jsonplus\serializationadapter\impl\phpjson\PHPJsonSerializationAdapter;
5+
use de\interaapps\jsonplus\serializationadapter\SerializationAdapter;
6+
use de\interaapps\jsonplus\typemapper\ObjectTypeMapper;
7+
use de\interaapps\jsonplus\typemapper\PassThroughTypeMapper;
8+
use de\interaapps\jsonplus\typemapper\TypeMapper;
9+
use ReflectionClass;
10+
11+
class JSONPlus {
12+
private bool $prettyPrinting = false;
13+
private array $typeMapper = [];
14+
private TypeMapper $defaultTypeMapper;
15+
private TypeMapper $passThroughTypeMapper;
16+
public static JSONPlus $default;
17+
18+
public function __construct(
19+
private SerializationAdapter $serializationAdapter
20+
){
21+
$this->defaultTypeMapper = new ObjectTypeMapper($this);
22+
$this->passThroughTypeMapper = new PassThroughTypeMapper();
23+
$this->typeMapper = [
24+
"object" => $this->passThroughTypeMapper,
25+
"string" => $this->passThroughTypeMapper,
26+
"float" => $this->passThroughTypeMapper,
27+
"int" => $this->passThroughTypeMapper,
28+
"double" => $this->passThroughTypeMapper,
29+
"bool" => $this->passThroughTypeMapper,
30+
"array" => $this->passThroughTypeMapper,
31+
"boolean" => $this->passThroughTypeMapper,
32+
];
33+
}
34+
35+
public function fromJson($json, $type=null){
36+
return $this->map($this->serializationAdapter->fromJson($json), $type);
37+
}
38+
39+
public function map($o, $type = null){
40+
if ($type == null)
41+
$type = get_class($o);
42+
43+
foreach ($this->typeMapper as $typeName => $typeMapper) {
44+
if ($type == $typeName)
45+
return $typeMapper->map($o, $type);
46+
}
47+
return $this->defaultTypeMapper->map($o, $type);
48+
}
49+
50+
public function toJson($o, $type = null) : string {
51+
return $this->serializationAdapter->toJson($this->mapToJson($o, $type), $this->prettyPrinting);
52+
}
53+
54+
public function mapToJson($o, $type = null){
55+
if ($type == null)
56+
$type = get_class($o);
57+
foreach ($this->typeMapper as $typeName => $typeMapper) {
58+
if ($type == $typeName)
59+
return $typeMapper->mapToJson($o, $type);
60+
}
61+
return $this->defaultTypeMapper->mapToJson($o, $type);
62+
}
63+
64+
public function getSerializationAdapter(): SerializationAdapter {
65+
return $this->serializationAdapter;
66+
}
67+
68+
public function setPrettyPrinting(bool $prettyPrinting): JSONPlus {
69+
$this->prettyPrinting = $prettyPrinting;
70+
return $this;
71+
}
72+
73+
public static function createDefault() : JSONPlus {
74+
return new JSONPlus(new PHPJsonSerializationAdapter());
75+
}
76+
}
77+
JSONPlus::$default = JSONPlus::createDefault();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace de\interaapps\jsonplus\attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute]
8+
class Serialize {
9+
public function __construct(
10+
public ?string $value = null,
11+
public bool $hidden = false
12+
){
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
namespace de\interaapps\jsonplus\serializationadapter;
3+
4+
interface SerializationAdapter {
5+
public function fromJson($json);
6+
public function toJson($v, bool $prettyPrint);
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
namespace de\interaapps\jsonplus\serializationadapter\impl\phpjson;
3+
4+
use de\interaapps\jsonplus\serializationadapter\SerializationAdapter;
5+
6+
class PHPJsonSerializationAdapter implements SerializationAdapter {
7+
public function fromJson($json){
8+
return json_decode($json);
9+
}
10+
11+
public function toJson($v, bool $prettyPrint) {
12+
if ($prettyPrint)
13+
return json_encode($v, JSON_PRETTY_PRINT);
14+
15+
return json_encode($v);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
namespace de\interaapps\jsonplus\typemapper;
3+
4+
5+
use de\interaapps\jsonplus\attributes\Serialize;
6+
use de\interaapps\jsonplus\JSONPlus;
7+
use ReflectionClass;
8+
9+
class ObjectTypeMapper implements TypeMapper {
10+
public function __construct(
11+
private JSONPlus $jsonPlus
12+
){
13+
}
14+
15+
public function map(mixed $o, string $type): mixed {
16+
$class = new ReflectionClass($type);
17+
$oo = $class->newInstance();
18+
19+
foreach ($class->getProperties() as $property) {
20+
if (!$property->isStatic()) {
21+
$name = $property?->getName();
22+
$serializeAttribs = $property->getAttributes(Serialize::class);
23+
foreach ($serializeAttribs as $attrib) {
24+
$attrib = $attrib->newInstance();
25+
$name = $attrib->value;
26+
if ($attrib->hidden)
27+
continue 2;
28+
}
29+
30+
if ($o != null && isset($o->{$name}))
31+
$property->setValue($oo, $this->jsonPlus->map($o?->{$name}, strval($property->getType())));
32+
}
33+
}
34+
35+
return $oo;
36+
}
37+
38+
public function mapToJson(mixed $o, string $type): mixed {
39+
$class = new ReflectionClass($type);
40+
$oo = [];
41+
foreach ($class->getProperties() as $property) {
42+
if (!$property->isStatic()) {
43+
$name = $property?->getName();
44+
$overrideName = $property?->getName();
45+
$serializeAttribs = $property->getAttributes(Serialize::class);
46+
foreach ($serializeAttribs as $attrib) {
47+
$attrib = $attrib->newInstance();
48+
$overrideName = $attrib->value;
49+
if ($attrib->hidden)
50+
continue 2;
51+
}
52+
53+
if ($o != null && isset($o->{$name}))
54+
$oo[$overrideName] = $o?->{$name};
55+
}
56+
}
57+
return (object) $oo;
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
namespace de\interaapps\jsonplus\typemapper;
3+
4+
5+
class PassThroughTypeMapper implements TypeMapper {
6+
public function map(mixed $o, string $type): mixed {
7+
return $o;
8+
}
9+
10+
public function mapToJson(mixed $o, string $type): mixed {
11+
return $o;
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
namespace de\interaapps\jsonplus\typemapper;
3+
4+
interface TypeMapper {
5+
public function map(mixed $o, string $type) : mixed;
6+
public function mapToJson(mixed $o, string $type) : mixed;
7+
}

0 commit comments

Comments
 (0)