11<?php
22
3- namespace Tools ;
3+ namespace Tool ;
44
55class Generator
66 {
77 private string $ rootPath = 'src/ConstantContact/ ' ;
88
9- private string $ definitionNamespace = 'PHPFUI \\ConstantContact \\Definition ' ;
9+ private string $ definitionNamespace = '\\ PHPFUI \\ConstantContact \\Definition ' ;
1010
1111 private string $ nl ;
1212
1313 private array $ duplicateClasses = [
1414 'CustomFieldResource2 ' => 'CustomFieldResource ' ,
1515 'ContactResource2 ' => 'ContactResource ' ,
1616 'ContactList2 ' => 'ContactList ' ,
17+ 'Lin ' => 'Link ' ,
18+ 'Link2 ' => 'Link ' ,
19+ 'Links ' => 'Link ' ,
20+ 'PagingLinks2 ' => 'PagingLinks ' ,
21+ 'Results ' => 'Result ' ,
1722 'Tag2 ' => 'Tag ' ,
1823 'Status ' => 'Status ' ,
1924 'Source ' => 'Source ' ,
@@ -26,6 +31,11 @@ public function __construct()
2631 $ this ->nl = 'WIN ' === \strtoupper (\substr (PHP_OS , 0 , 3 )) ? "\r\n" : "\n" ;
2732 }
2833
34+ public function deleteClasses (string $ version ) : void
35+ {
36+ $ this ->deleteFileTree ($ version );
37+ }
38+
2939 public function makeClasses (string $ version , array $ paths ) : void
3040 {
3141 \ksort ($ paths );
@@ -50,21 +60,30 @@ public function generateClass(string $version, string $path, array $properties)
5060 \mkdir ($ dir , recursive: true );
5161 }
5262
53- $ class = $ this ->getUniqueClassName ($ namespace , $ class );
63+ $ namespacedClass = $ this ->getUniqueClassName ($ namespace , $ class );
64+
65+ $ this ->writeClass ($ namespacedClass , $ apiPath , $ properties );
66+ }
5467
55- $ this ->writeClass ($ namespace , $ class , $ apiPath , $ properties );
68+ public function deleteDefinitions () : void
69+ {
70+ $ this ->deleteFileTree ('/Definition ' );
5671 }
5772
5873 public function makeDefinitions (array $ definitions ) : void
5974 {
6075 foreach ($ definitions as $ class => $ properties )
6176 {
62- $ this ->generateDefinition ($ class , $ properties );
77+ $ this ->generateDefinition ($ this -> getUniqueClassName ( $ this -> definitionNamespace , $ class) , $ properties );
6378 }
6479 }
6580
66- public function generateDefinition (string $ class , array $ properties ) : void
81+ public function generateDefinition (string $ namespacedClass , array $ properties ) : void
6782 {
83+ $ parts = explode ('\\' , $ namespacedClass );
84+ $ class = array_pop ($ parts );
85+ $ namespace = implode ('\\' , $ parts );
86+
6887 if (! isset ($ properties ['type ' ]))
6988 {
7089 return ;
@@ -99,9 +118,8 @@ public function generateDefinition(string $class, array $properties) : void
99118 if ('object ' == $ type )
100119 {
101120 $ namespace = $ this ->definitionNamespace ;
102- $ baseName = $ this ->getUniqueClassName ($ namespace , $ this ->getClassName ($ name ));
103- $ type = '\\' . $ namespace . '\\' . $ baseName ;
104- $ this ->generateDefinition ($ baseName , $ details );
121+ $ type = $ this ->getUniqueClassName ($ this ->definitionNamespace , $ name );
122+ $ this ->generateDefinition ($ type , $ details );
105123 }
106124
107125 if (isset ($ details ['format ' ]))
@@ -160,60 +178,69 @@ public function generateDefinition(string $class, array $properties) : void
160178 $ maxLength [$ name ] = (int )$ details ['maxLength ' ];
161179 }
162180
181+ $ description = '' ;
163182 if (isset ($ details ['description ' ]))
164183 {
165184 $ description = $ this ->cleanDescription (\trim ($ details ['description ' ]));
185+ }
166186
167- if (\is_array ($ type ))
168- {
169- $ type = $ originalType ;
170- }
171- $ type = \str_replace ('\\\\' , '\\' , $ type );
172- $ docBlock [] = "{$ type } {$ dollar }{$ name } {$ description }" ;
187+ if (\is_array ($ type ))
188+ {
189+ $ type = $ originalType ;
173190 }
191+ $ type = \str_replace ('\\\\' , '\\' , $ type );
192+ $ docBlock [] = trim ("{$ type } {$ dollar }{$ name } {$ description }" );
174193 }
175194 $ this ->generateFromTemplate ($ class , ['fields ' => $ fields , 'minLength ' => $ minLength , 'maxLength ' => $ maxLength , ], $ docBlock );
176195 }
177196 }
178197
198+ /**
199+ * Given a namespace and a class in the namespace, get a unique name that combines duplicate classes
200+ *
201+ * @return string fully namespaced class name
202+ */
179203 private function getUniqueClassName (string $ namespace , string $ class ) : string
180204 {
205+ $ namespace = trim ($ namespace , '\\' );
206+ $ class = $ this ->getClassName ($ class );
181207 if (isset ($ this ->duplicateClasses [$ class ]))
182208 {
183- return $ this ->duplicateClasses [$ class ];
209+ $ class = $ this ->duplicateClasses [$ class ];
210+ $ fullName = '\\' . $ namespace . '\\' . $ class ;
211+ $ this ->generatedClasses [$ fullName ] = true ;
212+
213+ return $ fullName ;
184214 }
185215
186- $ fullName = $ namespace . '\\' . $ class ;
216+ $ fullName = '\\' . $ namespace . '\\' . $ class ;
187217
188- if (isset ($ this ->generatedClasses [$ fullName ]))
218+ // if we have seen this class before, then it is the plural version and it should be singular because CC does not know how to design an API (among other things).
219+ if (! str_contains ($ fullName , 'Definition ' ) && isset ($ this ->generatedClasses [$ fullName ]))
189220 {
190- if ('Links ' == $ class )
191- {
192- $ class = 'Link ' ;
193- }
194- elseif ('StreetAddress ' == $ class )
195- {
196- $ class = 'StreetAddressRecord ' ;
197- }
198- // trim the s off the end point for the singular
199- elseif (\str_ends_with ($ class , 'ies ' ))
221+ if (\str_ends_with ($ class , 'ies ' ))
200222 {
201223 $ class = \substr ($ class , 0 , \strlen ($ class ) - 3 );
202224 $ class .= 'y ' ;
203225 }
204- else
226+ else // trim the s off the end point for the singular
205227 {
206228 $ class = \substr ($ class , 0 , \strlen ($ class ) - 1 );
207229 }
208- $ fullName = $ namespace . '\\' . $ class ;
230+ $ fullName = '\\' . $ namespace . '\\' . $ class ;
209231 }
232+
210233 $ this ->generatedClasses [$ fullName ] = true ;
211234
212- return $ class ;
235+ return $ fullName ;
213236 }
214237
215- private function writeClass (string $ namespace , string $ class , string $ apiPath , array $ properties ) : void
238+ private function writeClass (string $ namespacedClass , string $ apiPath , array $ properties ) : void
216239 {
240+ $ parts = explode ('\\' , $ namespacedClass );
241+ $ class = array_pop ($ parts );
242+ $ namespace = trim (implode ('\\' , $ parts ), '\\' );
243+
217244 $ methods = '' ;
218245 $ dollar = '$ ' ;
219246
@@ -379,7 +406,7 @@ private function getPHPType(string $type) : string
379406 }
380407 elseif ('date-time ' == $ type )
381408 {
382- $ type = 'DateTime ' ;
409+ $ type = '\PHPFUI\ConstantContact\ DateTime ' ;
383410 }
384411 elseif ('date ' == $ type )
385412 {
@@ -462,15 +489,23 @@ private function formatDescription(string $description) : string
462489 return \implode ("\n" , $ blocks );
463490 }
464491
492+ /**
493+ * Generate a definition from a template
494+ *
495+ * @param string $name of the class, no namespace
496+ * @param array $properties from YAML file
497+ * @param array $docBlocks @var docblocks to output
498+ */
465499 private function generateFromTemplate (string $ name , array $ properties , array $ docBlocks ) : void
466500 {
467- $ backSlash = '\\' ;
501+ $ namespace = trim ($ this ->definitionNamespace , '\\' );
502+
468503 $ template = <<<PHP
469504<?php
470505
471506// Generated file. Do not edit by hand. Use update.php in project root.
472507
473- namespace {$ this -> definitionNamespace };
508+ namespace {$ namespace };
474509
475510/**
476511
@@ -483,7 +518,7 @@ private function generateFromTemplate(string $name, array $properties, array $do
483518 }
484519
485520 $ template .= " */
486- class ~class~ extends {$ backSlash }{ $ this ->definitionNamespace }\Base
521+ class ~class~ extends {$ this ->definitionNamespace }\Base
487522 { " ;
488523
489524 foreach ($ properties as $ fields => $ values )
@@ -544,6 +579,29 @@ private function getTypeNameFromRef(string $ref) : string
544579 {
545580 $ parts = \explode ('/ ' , \str_replace ('_ ' , '' , $ ref ));
546581
547- return '\\' . $ this ->definitionNamespace . '\\' . \array_pop ($ parts );
582+ return $ this ->getUniqueClassName ($ this ->definitionNamespace , \array_pop ($ parts ));
583+ }
584+
585+ private function deleteFileTree (string $ path ) : void
586+ {
587+ $ directory = __DIR__ . '/../src/ConstantContact ' . $ path ;
588+
589+ $ iterator = new \RecursiveIteratorIterator (
590+ new \RecursiveDirectoryIterator ($ directory , \RecursiveDirectoryIterator::SKIP_DOTS ),
591+ \RecursiveIteratorIterator::SELF_FIRST );
592+
593+ foreach ($ iterator as $ item )
594+ {
595+ if (! $ item ->isDir ())
596+ {
597+ $ fileName = "{$ item }" ;
598+ // don't delete base classes
599+ if (! str_ends_with ($ fileName , 'Base.php ' ))
600+ {
601+ unlink ($ fileName );
602+ }
603+ }
604+ }
548605 }
606+
549607 }
0 commit comments