99use IteratorAggregate ;
1010use Soap \Engine \Exception \MetadataException ;
1111use Soap \Engine \Metadata \Model \Type ;
12+ use function array_key_exists ;
13+ use function Psl \Dict \reindex ;
1214
1315/**
1416 * @implements IteratorAggregate<int<0,max>, Type>
@@ -20,12 +22,24 @@ final class TypeCollection implements Countable, IteratorAggregate
2022 */
2123 private array $ types ;
2224
25+ /**
26+ * @var array<string, Type>
27+ */
28+ private array $ qualifiedLookup ;
29+
2330 /**
2431 * @no-named-arguments
2532 */
2633 public function __construct (Type ...$ types )
2734 {
2835 $ this ->types = $ types ;
36+ $ this ->qualifiedLookup = reindex (
37+ $ types ,
38+ static fn (Type $ type ): string => self ::createLookupKey (
39+ $ type ->getXsdType ()->getName (),
40+ $ type ->getXsdType ()->getXmlNamespace ()
41+ )
42+ );
2943 }
3044
3145 /**
@@ -99,12 +113,16 @@ public function fetchFirstByName(string $name): Type
99113 */
100114 public function fetchByNameAndXmlNamespace (string $ name , string $ namespace ): Type
101115 {
102- foreach ($ this ->types as $ type ) {
103- if ($ name === $ type ->getName () && $ namespace === $ type ->getXsdType ()->getXmlNamespace ()) {
104- return $ type ;
105- }
116+ $ lookupKey = self ::createLookupKey ($ name , $ namespace );
117+ if (!array_key_exists ($ lookupKey , $ this ->qualifiedLookup )) {
118+ throw MetadataException::typeNotFound ($ name );
106119 }
107120
108- throw MetadataException::typeNotFound ($ name );
121+ return $ this ->qualifiedLookup [$ lookupKey ];
122+ }
123+
124+ private static function createLookupKey (string $ name , string $ namespace ): string
125+ {
126+ return $ namespace . ': ' . $ name ;
109127 }
110128}
0 commit comments