1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Pfilsx \PostgreSQLDoctrine \DBAL \Type ;
6+
7+ use Doctrine \DBAL \Exception ;
8+ use Doctrine \DBAL \Types \Type ;
9+ use Symfony \Component \PropertyInfo \Extractor \ReflectionExtractor ;
10+ use Symfony \Component \Serializer \NameConverter \CamelCaseToSnakeCaseNameConverter ;
11+ use Symfony \Component \Serializer \Normalizer \AbstractObjectNormalizer ;
12+ use Symfony \Component \Serializer \Normalizer \ObjectNormalizer ;
13+
14+ final class JsonModelTypeRegistry
15+ {
16+ private static AbstractObjectNormalizer $ objectNormalizer ;
17+
18+ private static array $ typesMap = [];
19+
20+ /**
21+ * @param string $name
22+ * @param class-string $className
23+ * @param bool $override
24+ * @return void
25+ * @throws Exception
26+ */
27+ public static function addType (string $ name , string $ className , bool $ override = false ): void
28+ {
29+ if (!$ override && array_key_exists ($ name , self ::$ typesMap )) {
30+ throw Exception::typeExists ($ name );
31+ }
32+
33+ if (!class_exists ($ className ) || !is_subclass_of ($ className , JsonModelType::class)) {
34+ throw new Exception (
35+ sprintf ('Type class name should be a subclass of %s. %s provided ' , JsonModelType::class, $ className )
36+ );
37+ }
38+
39+ self ::$ typesMap [$ name ] = $ className ;
40+ }
41+
42+ public static function hasType (string $ name ): bool
43+ {
44+ return array_key_exists ($ name , self ::$ typesMap );
45+ }
46+
47+ public static function getObjectNormalizer (): AbstractObjectNormalizer
48+ {
49+ return self ::$ objectNormalizer ??= new ObjectNormalizer (
50+ nameConverter: new CamelCaseToSnakeCaseNameConverter (),
51+ propertyTypeExtractor: new ReflectionExtractor ()
52+ );
53+ }
54+ public static function setObjectNormalizer (AbstractObjectNormalizer $ objectNormalizer ): void
55+ {
56+ self ::$ objectNormalizer = $ objectNormalizer ;
57+ }
58+ public static function registerTypes (): void
59+ {
60+ $ typeRegistry = Type::getTypeRegistry ();
61+ $ objectNormalizer = self ::getObjectNormalizer ();
62+ foreach (self ::$ typesMap as $ name => $ className ) {
63+ /** @var JsonModelType $type */
64+ $ type = new $ className ();
65+ $ type ->setObjectNormalizer ($ objectNormalizer );
66+
67+ $ typeRegistry ->register ($ name , $ type );
68+ }
69+ }
70+ }
0 commit comments