diff --git a/.gitignore b/.gitignore index a67d42b..cbf029e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ composer.phar /vendor/ +/.phpunit.result.cache # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file diff --git a/README.md b/README.md index 7ba5fb1..9538704 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,22 @@ It will map all properties (including private and protected), as long they are n ### Sample object class The properties can be configured with doctrine annotations or the new PHP 8 attributes. A full documentation of the annotations/attributes is following. + ```php class ClassToConvert { - #[\Tarikweiss\Tjson\Attributes\MappedPropertyName(name: 'public_item')] + #[\Tjson\Attributes\MappedPropertyName(name: 'public_item')] public $publicItem; protected $protectedItem; private $privateItem; - #[\Tarikweiss\Tjson\Attributes\MappedPropertyClass(class: ClassC::class)] + #[\Tjson\Attributes\MappedPropertyClass(class: ClassC::class)] private ClassA|ClassB|ClassC $typedItems; /** - * @\Tarikweiss\Tjson\Attributes\Required(required = true) + * @\Tjson\Attributes\Required(required = true) */ private $anotherProperty = 'withValue'; @@ -47,8 +48,9 @@ This json is assumed as value for `$jsonString` for the following samples: ```` #### Decoder Decoding is done as follows: + ```php -$jsonDecoder = new \Tarikweiss\Tjson\JsonDecoder(); +$jsonDecoder = new \Tjson\JsonDecoder(); $yourClassInstance = $jsonDecoder->decodeByClassName($jsonString, \Your\Class::class) echo $yourClassInstance->getProtectedItem() // 1337 @@ -56,8 +58,9 @@ echo $yourClassInstance->getProtectedItem() // 1337 #### Encoder Encoding is done as follows: + ```php -$jsonEncoder = new \Tarikweiss\Tjson\JsonEncoder(); +$jsonEncoder = new \Tjson\JsonEncoder(); $jsonString = $jsonEncoder->encode($yourClassInstance); ``` diff --git a/composer.json b/composer.json index ce439dc..381079e 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "autoload": { "psr-4": { - "Tarikweiss\\Tjson\\": "src/" + "Tjson\\": "src/" } }, "require-dev": { diff --git a/src/Attributes/MappedPropertyClass.php b/src/Attributes/MappedPropertyClass.php index 17f2090..b0bf08a 100644 --- a/src/Attributes/MappedPropertyClass.php +++ b/src/Attributes/MappedPropertyClass.php @@ -1,13 +1,13 @@ * If only a single type is specified and class name does not match, an exception will be thrown. - * @package Tarikweiss\Tjson\Attributes + * @package Tjson\Attributes * @Annotation * @\Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor */ diff --git a/src/Attributes/MappedPropertyName.php b/src/Attributes/MappedPropertyName.php index 945748a..f6ef194 100644 --- a/src/Attributes/MappedPropertyName.php +++ b/src/Attributes/MappedPropertyName.php @@ -1,11 +1,11 @@ getTypes($reflectedProperty); if (property_exists($decodedJson, $jsonPropertyName) === false) { if ($required === true) { - throw new \Tarikweiss\Tjson\Exception\RequiredPropertyNotFoundException(sprintf('Required class property \'%s\' not found in json.', $reflectedProperty->getName())); + throw new \Tjson\Exception\RequiredPropertyNotFoundException(sprintf('Required class property \'%s\' not found in json.', $reflectedProperty->getName())); } continue; } @@ -90,7 +90,7 @@ public function decodeByObject(string $json, object $object) if (count($types) === 1) { $type = $types[0]; - $jsonValueTypeDoesMatch = \Tarikweiss\Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, $type->getName()); + $jsonValueTypeDoesMatch = \Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, $type->getName()); if ($jsonValueTypeDoesMatch === false) { switch ($jsonValueType) { case 'object': @@ -109,7 +109,7 @@ public function decodeByObject(string $json, object $object) } default: { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('No matching type found for json property \'' . $jsonPropertyName . '\''); + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('No matching type found for json property \'' . $jsonPropertyName . '\''); } } } @@ -121,19 +121,19 @@ public function decodeByObject(string $json, object $object) foreach ($types as $type) { if ($type->isBuiltin() === false) { $customTypesCount++; - $typeThatIsNotBuiltIn = new \Tarikweiss\Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin()); + $typeThatIsNotBuiltIn = new \Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin()); } if ($customTypesCount > 1) { - throw new \Tarikweiss\Tjson\Exception\AmbiguousTypeDefinitionException('Cannot infer type for class property' . $reflectedProperty->getName()); + throw new \Tjson\Exception\AmbiguousTypeDefinitionException('Cannot infer type for class property' . $reflectedProperty->getName()); } - $jsonValueTypeDoesMatch = \Tarikweiss\Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, $type->getName()); + $jsonValueTypeDoesMatch = \Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, $type->getName()); $hasEvenMatch = $jsonValueTypeDoesMatch | $hasEvenMatch; } if ($typeThatIsNotBuiltIn !== null && is_object($jsonValue) === true) { $jsonValue = $this->decodeByClassName(json_encode($jsonValue), $typeThatIsNotBuiltIn->getName()); } if (false === $hasEvenMatch) { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('Defined types do not contain type of json value.'); + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('Defined types do not contain type of json value.'); } } @@ -161,12 +161,12 @@ public function decodeByObject(string $json, object $object) * @param mixed $jsonValueType * @param bool $nullable * - * @throws \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException + * @throws \Tjson\Exception\NoMatchingTypeDefinitionException */ private function nullCheck($jsonValueType, bool $nullable): void { - if (\Tarikweiss\Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, 'NULL') === true && $nullable === false) { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('Defined types do not contain type of json value.'); + if (\Tjson\Util\PropertyUtil::doTypesMatch($jsonValueType, 'NULL') === true && $nullable === false) { + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('Defined types do not contain type of json value.'); } } @@ -174,12 +174,12 @@ private function nullCheck($jsonValueType, bool $nullable): void /** * @param \ReflectionProperty $reflectedProperty * - * @return \Tarikweiss\Tjson\Decoding\AbstractedType[] + * @return \Tjson\Decoding\AbstractedType[] */ private function getTypes(\ReflectionProperty $reflectedProperty): array { /** - * @var \Tarikweiss\Tjson\Attributes\MappedPropertyClass $mappedPropertyClassInstance + * @var \Tjson\Attributes\MappedPropertyClass $mappedPropertyClassInstance */ $types = []; $intersectionType = false; @@ -187,19 +187,19 @@ private function getTypes(\ReflectionProperty $reflectedProperty): array $type = $reflectedProperty->getType(); if ($type instanceof \ReflectionNamedType === true) { - $types[] = (new \Tarikweiss\Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); + $types[] = (new \Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); } if ($type instanceof \ReflectionUnionType === true) { foreach ($type->getTypes() as $type) { - $types[] = (new \Tarikweiss\Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); + $types[] = (new \Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); } } if ($type instanceof \ReflectionIntersectionType === true) { $intersectionType = true; foreach ($type->getTypes() as $type) { - $types[] = (new \Tarikweiss\Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); + $types[] = (new \Tjson\Decoding\AbstractedType($type->getName(), $type->isBuiltin())); } } } @@ -213,7 +213,7 @@ private function getTypes(\ReflectionProperty $reflectedProperty): array if (count($types) === 1) { $type = $types[0]; if ($type->getName() !== $mappedType) { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('Mapped property class is not matching given type.'); + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('Mapped property class is not matching given type.'); } } if (count($types) > 1) { @@ -226,7 +226,7 @@ private function getTypes(\ReflectionProperty $reflectedProperty): array } } if ($foundMatching === false) { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('Could not find any matching type definition for '); + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('Could not find any matching type definition for '); } } if ($intersectionType === true) { @@ -240,7 +240,7 @@ private function getTypes(\ReflectionProperty $reflectedProperty): array } if ($isMatchingAll === false) { - throw new \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException('The mapped property class \'' . $mappedType . '\' does not match the intersection type.'); + throw new \Tjson\Exception\NoMatchingTypeDefinitionException('The mapped property class \'' . $mappedType . '\' does not match the intersection type.'); } } } @@ -260,13 +260,13 @@ private function getMappedType(\ReflectionProperty $reflectedProperty): ?string $mappedType = null; $reader = new \Doctrine\Common\Annotations\AnnotationReader(); - $annotation = $reader->getPropertyAnnotation($reflectedProperty, \Tarikweiss\Tjson\Attributes\MappedPropertyClass::class); - if ($annotation instanceof \Tarikweiss\Tjson\Attributes\MappedPropertyClass === true) { + $annotation = $reader->getPropertyAnnotation($reflectedProperty, \Tjson\Attributes\MappedPropertyClass::class); + if ($annotation instanceof \Tjson\Attributes\MappedPropertyClass === true) { $mappedType = $annotation->getClass(); } - if (\Tarikweiss\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { - $mappedPropertyClassAttributes = $reflectedProperty->getAttributes(\Tarikweiss\Tjson\Attributes\MappedPropertyClass::class); + if (\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { + $mappedPropertyClassAttributes = $reflectedProperty->getAttributes(\Tjson\Attributes\MappedPropertyClass::class); foreach ($mappedPropertyClassAttributes as $mappedPropertyClassAttribute) { $mappedPropertyClassInstance = $mappedPropertyClassAttribute->newInstance(); $class = $mappedPropertyClassInstance->getClass(); diff --git a/src/JsonEncoder.php b/src/JsonEncoder.php index 7b58443..3fe8e26 100644 --- a/src/JsonEncoder.php +++ b/src/JsonEncoder.php @@ -1,11 +1,11 @@ setAccessible(true); if ($reflectedProperty->isInitialized($object) === false) { if ($required === true) { - throw new \Tarikweiss\Tjson\Exception\RequiredPropertyNotFoundException(sprintf('The required property \'%s\' is not initialized.', $jsonPropertyName)); + throw new \Tjson\Exception\RequiredPropertyNotFoundException(sprintf('The required property \'%s\' is not initialized.', $jsonPropertyName)); } continue; } diff --git a/src/Util/PropertyUtil.php b/src/Util/PropertyUtil.php index b95ea7a..3a52ecd 100644 --- a/src/Util/PropertyUtil.php +++ b/src/Util/PropertyUtil.php @@ -1,11 +1,11 @@ getPropertyAnnotation($reflectedProperty, \Tarikweiss\Tjson\Attributes\MappedPropertyName::class); + $mappedPropertyNameInstance = $doctrineAnnotationReader->getPropertyAnnotation($reflectedProperty, \Tjson\Attributes\MappedPropertyName::class); if ($mappedPropertyNameInstance !== null) { $jsonPropertyName = $mappedPropertyNameInstance->getName(); } if (VersionUtil::isPhp8OrNewer() === true) { - $reflectedAttributes = $reflectedProperty->getAttributes(\Tarikweiss\Tjson\Attributes\MappedPropertyName::class); + $reflectedAttributes = $reflectedProperty->getAttributes(\Tjson\Attributes\MappedPropertyName::class); foreach ($reflectedAttributes as $reflectedAttribute) { $mappedPropertyNameInstance = $reflectedAttribute->newInstance(); $jsonPropertyName = $mappedPropertyNameInstance->getName(); @@ -73,18 +73,18 @@ public static function getJsonPropertyNameByClassProperty(\ReflectionProperty $r public static function isRequired(\ReflectionProperty $reflectedProperty): bool { /** - * @var \Tarikweiss\Tjson\Attributes\Required $requiredAttributeInstance + * @var \Tjson\Attributes\Required $requiredAttributeInstance */ $required = $reflectedProperty->hasType(); $reader = new \Doctrine\Common\Annotations\AnnotationReader(); - $annotation = $reader->getPropertyAnnotation($reflectedProperty, \Tarikweiss\Tjson\Attributes\Required::class); - if ($annotation instanceof \Tarikweiss\Tjson\Attributes\Required === true) { + $annotation = $reader->getPropertyAnnotation($reflectedProperty, \Tjson\Attributes\Required::class); + if ($annotation instanceof \Tjson\Attributes\Required === true) { $required = $annotation->isRequired(); } - if (\Tarikweiss\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { - $attributes = $reflectedProperty->getAttributes(\Tarikweiss\Tjson\Attributes\Required::class); + if (\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { + $attributes = $reflectedProperty->getAttributes(\Tjson\Attributes\Required::class); foreach ($attributes as $attribute) { $requiredAttributeInstance = $attribute->newInstance(); $required = $requiredAttributeInstance->isRequired(); @@ -103,18 +103,18 @@ public static function isRequired(\ReflectionProperty $reflectedProperty): bool public static function isOmitted(\ReflectionProperty $reflectedProperty): bool { /** - * @var \Tarikweiss\Tjson\Attributes\Omit $omitAttributeInstance + * @var \Tjson\Attributes\Omit $omitAttributeInstance */ $omit = false; $reader = new \Doctrine\Common\Annotations\AnnotationReader(); - $omitAnnotation = $reader->getPropertyAnnotation($reflectedProperty, \Tarikweiss\Tjson\Attributes\Omit::class); - if ($omitAnnotation instanceof \Tarikweiss\Tjson\Attributes\Omit === true) { + $omitAnnotation = $reader->getPropertyAnnotation($reflectedProperty, \Tjson\Attributes\Omit::class); + if ($omitAnnotation instanceof \Tjson\Attributes\Omit === true) { $omit = $omitAnnotation->isOmit(); } - if (\Tarikweiss\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { - $omitAttributes = $reflectedProperty->getAttributes(\Tarikweiss\Tjson\Attributes\Omit::class); + if (\Tjson\Util\VersionUtil::isPhp8OrNewer() === true) { + $omitAttributes = $reflectedProperty->getAttributes(\Tjson\Attributes\Omit::class); foreach ($omitAttributes as $omitAttribute) { $omitAttributeInstance = $omitAttribute->newInstance(); $omit = $omitAttributeInstance->isOmit(); diff --git a/src/Util/ReflectionUtil.php b/src/Util/ReflectionUtil.php index f1e13cc..06d6832 100644 --- a/src/Util/ReflectionUtil.php +++ b/src/Util/ReflectionUtil.php @@ -1,11 +1,11 @@ boolProperty = false; $jsonString = '{"int":10,"bool":true,"string":"Some fantastic string!","float":17.5,"array":[1,2,3,4,5,6],"object":{"intProperty":10,"boolProperty":false}}'; - $decoder = (new \Tarikweiss\Tjson\JsonDecoder()); + $decoder = (new \Tjson\JsonDecoder()); $foo = $decoder->decodeByClassName($jsonString, Foo::class); $this->assertInstanceOf(Foo::class, $foo); $this->assertSame(10, $foo->getInt()); @@ -28,16 +28,16 @@ public function testDecode() * @dataProvider decodeFailsOnNoMatchingTypeDefinitionDataProvider * @return void * @throws \ReflectionException - * @throws \Tarikweiss\Tjson\Exception\AmbiguousNameDefinitionException - * @throws \Tarikweiss\Tjson\Exception\AmbiguousTypeDefinitionException - * @throws \Tarikweiss\Tjson\Exception\ClassNotFoundException - * @throws \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException - * @throws \Tarikweiss\Tjson\Exception\RequiredPropertyNotFoundException + * @throws \Tjson\Exception\AmbiguousNameDefinitionException + * @throws \Tjson\Exception\AmbiguousTypeDefinitionException + * @throws \Tjson\Exception\ClassNotFoundException + * @throws \Tjson\Exception\NoMatchingTypeDefinitionException + * @throws \Tjson\Exception\RequiredPropertyNotFoundException */ public function testDecodeFailsOnNoMatchingTypeDefinition($jsonString, $field) { - $decoder = (new \Tarikweiss\Tjson\JsonDecoder()); - $this->expectException(\Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException::class); + $decoder = (new \Tjson\JsonDecoder()); + $this->expectException(\Tjson\Exception\NoMatchingTypeDefinitionException::class); $this->expectExceptionMessage('No matching type found for json property \'' . $field . '\''); $decoder->decodeByClassName($jsonString, Foo::class); } diff --git a/tests/unit/RequiredDetectionTest.php b/tests/unit/RequiredDetectionTest.php index 5ceca6e..be58db3 100644 --- a/tests/unit/RequiredDetectionTest.php +++ b/tests/unit/RequiredDetectionTest.php @@ -11,21 +11,21 @@ class RequiredDetectionTest extends \PHPUnit\Framework\TestCase * * @return void * @throws \ReflectionException - * @throws \Tarikweiss\Tjson\Exception\AmbiguousNameDefinitionException - * @throws \Tarikweiss\Tjson\Exception\AmbiguousTypeDefinitionException - * @throws \Tarikweiss\Tjson\Exception\ClassNotFoundException - * @throws \Tarikweiss\Tjson\Exception\NoMatchingTypeDefinitionException - * @throws \Tarikweiss\Tjson\Exception\RequiredPropertyNotFoundException + * @throws \Tjson\Exception\AmbiguousNameDefinitionException + * @throws \Tjson\Exception\AmbiguousTypeDefinitionException + * @throws \Tjson\Exception\ClassNotFoundException + * @throws \Tjson\Exception\NoMatchingTypeDefinitionException + * @throws \Tjson\Exception\RequiredPropertyNotFoundException * @dataProvider requiredDetectionOnDecodeDataProvider */ public function testRequiredDetectionOnDecode(string $json, bool $expectException) { $testObject = new TestObject(); - $jsonDecoder = new \Tarikweiss\Tjson\JsonDecoder(); + $jsonDecoder = new \Tjson\JsonDecoder(); if (true === $expectException) { - $this->expectException(\Tarikweiss\Tjson\Exception\RequiredPropertyNotFoundException::class); + $this->expectException(\Tjson\Exception\RequiredPropertyNotFoundException::class); } $jsonDecoder->decodeByObject($json, $testObject); @@ -69,7 +69,7 @@ class TestObject /** * @var string - * @\Tarikweiss\Tjson\Attributes\Required(required = true) + * @\Tjson\Attributes\Required(required = true) */ private $explicitRequired;