<?php
 namespace apimatic\jsonmapper; class TypeCombination { private $_format; private $_groupName; private $_types; private $_deserializers; private function __construct($format, $groupName, $types, $deserializers) { $this->_format = $format; $this->_groupName = $groupName; $this->_types = $types; $this->_deserializers = $deserializers; } public function getFormat() { return $this->_format; } public function getGroupName() { return $this->_groupName; } public function getTypes() { return $this->_types; } public function getDeserializers() { return $this->_deserializers; } public function extractOneOfAnyOfGroup() { $innerType = $this->getTypes()[0]; if (in_array($this->getGroupName(), ["array", "map"]) && $innerType instanceof TypeCombination ) { return $innerType->extractOneOfAnyOfGroup(); } return $this; } public function extractSimilar($group) { $result = []; if (!in_array($this->getGroupName(), ["array", "map"])) { foreach ($this->getTypes() as $typ) { if ($typ instanceof TypeCombination) { $result = array_merge($result, $typ->extractSimilar($group)); } } } elseif ($group->getGroupName() == $this->getGroupName()) { $internal = $this->getTypes()[0]; $group = $group->getTypes()[0]; if (in_array($group->getGroupName(), ["array", "map"])) { $result = $internal->extractSimilar($group); } else { $result = [$internal]; } } return $result; } public static function extractTypeInfo($type) { $mapStart = 'array<string,'; $isMap = substr($type, -1) == '>' && strpos($type, $mapStart) === 0; $isArray = substr($type, -2) == '[]'; $innerType = $isMap ? substr($type, strlen($mapStart), -1) : ($isArray ? substr($type, 0, -2) : $type); return [$isMap, $isArray, $innerType]; } public static function with($types, $gName = 'anyof', array $deserializers = []) { $format = join( ',', array_map( function ($t) { return is_string($t) ? $t : $t->getFormat(); }, $types ) ); return new self( "$gName($format)", $gName, $types, $deserializers ); } public static function withFormat($typeGroup, $deserializers = []) { $groupName = 'anyOf'; $start = strpos($typeGroup, '('); $end = strrpos($typeGroup, ')'); if ($start !== false && $end !== false) { list($isMap, $isArray, $innerType) = self::extractTypeInfo($typeGroup); if ($isMap || $isArray) { return self::_createTypeGroup( $isMap ? 'map' : 'array', $innerType, $deserializers ); } $name = substr($typeGroup, 0, $start); $groupName = empty($name) ? $groupName : $name; $typeGroup = substr($typeGroup, $start + 1, -1); } $format = "($typeGroup)"; $types = []; $type = ''; $groupCount = 0; foreach (str_split($typeGroup) as $c) { if ($c == '(' || $c == '<') { $groupCount++; } if ($c == ')' || $c == '>') { $groupCount--; } if ($c == ',' && $groupCount == 0) { self::_insertType($types, $type, $deserializers); $type = ''; continue; } $type .= $c; } self::_insertType($types, $type, $deserializers); return new self($format, $groupName, $types, $deserializers); } private static function _createTypeGroup($name, $innerGroup, $deserializers) { $format = $name == 'map' ? "array<string,$innerGroup>" : $innerGroup . '[]'; return new self( $format, $name, [self::withFormat($innerGroup, $deserializers)], $deserializers ); } private static function _insertType(&$types, $type, $deserializers) { $type = trim($type); if (strpos($type, '(') !== false && strrpos($type, ')') !== false) { $type = self::withFormat($type, $deserializers); } if (!empty($type)) { array_push($types, $type); } } } 